อัปเดตอาร์เรย์ที่เปลี่ยนแปลงไม่ได้ด้วย Array.promotype.with

เมื่อเร็วๆ นี้ เบราว์เซอร์ได้รับวิธีการใหม่ที่ทำงานร่วมกัน ซึ่งคุณสามารถเรียกใช้บนอาร์เรย์ได้: Array.prototype.with()

การรองรับเบราว์เซอร์

  • Chrome: 110.
  • ขอบ: 110
  • Firefox: 115
  • Safari: 16.

แหล่งที่มา

บทความนี้จะสำรวจวิธีการทำงานของเมธอดนี้และวิธีใช้เพื่ออัปเดตอาร์เรย์ โดยไม่เปลี่ยนแปลงอาร์เรย์ต้นฉบับ

แนะนำ Array.prototype.with(index, value)

เมธอด Array.prototype.with(index, value) จะแสดงสำเนาของอาร์เรย์ เรียกใช้โดยตั้งค่า index เป็น value ใหม่ที่คุณระบุ

ตัวอย่างต่อไปนี้แสดงอาร์เรย์ของอายุ คุณต้องการสร้างสำเนาใหม่ของ อาร์เรย์ขณะเปลี่ยนอายุที่สองจาก 15 เป็น 16

const ages = [10, 15, 20, 25];

const newAges = ages.with(1, 16);
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)

การแจกแจงโค้ด: ages.with(...) แสดงผลสําเนาของตัวแปร ages โดยไม่แก้ไขอาร์เรย์เดิม ages.with(1, …) แทนที่รายการที่ 2 (index = 1) ages.with(1, 16) กำหนดรายการที่ 2 ให้กับ 16

นี่คือวิธีการสร้างสำเนาใหม่ของอาร์เรย์ที่มีการแก้ไข

ซึ่งจะมีประโยชน์มาก เมื่อคุณต้องการตรวจสอบว่าอาร์เรย์เดิมยังคงอยู่ ไม่เปลี่ยนแปลง และบทความนี้ครอบคลุมกรณีการใช้งานบางอย่างในเรื่องนี้ แต่ตอนนี้ ดูว่าจะเกิดอะไรขึ้นหากคุณใช้เครื่องหมายวงเล็บเหลี่ยม:

const ages = [10, 15, 20, 25];

const newAges = ages;
newAges[1] = 16;
console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 16, 20, 25] (Also changed 🙁)

คุณจะเห็นว่าตัวแปร ages ได้รับการแก้ไขในตัวอย่างนี้เช่นกัน นั่นคือ เพราะเมื่อคุณกำหนด ages = newAges JavaScript จะไม่คัดลอกอาร์เรย์ จะสร้างการอ้างอิงไปยังอาร์เรย์อื่นแทน ดังนั้น การเปลี่ยนแปลงใดๆ ในส่วนขยาย จะมีผลกับอีกรายการเนื่องจากทั้ง 2 รายการชี้ไปยังอาร์เรย์เดียวกัน

Array.proftype.with() และการไม่เปลี่ยนแปลง

การไม่เปลี่ยนแปลงเป็นหัวใจสำคัญของไลบรารีฟรอนท์เอนด์และเฟรมเวิร์กจำนวนมาก 2-3: React (และทำซ้ำ) และ Vue

นอกจากนี้ ไลบรารีและเฟรมเวิร์กอื่นๆ ไม่ได้ต้องการการเปลี่ยนแปลง กระตุ้นให้มีประสิทธิภาพดีขึ้น: Angular และ Lit

ดังนั้น นักพัฒนาซอฟต์แวร์จึงมักจะต้องใช้วิธีอื่นที่แสดงสำเนาของอาร์เรย์ ซึ่งบั่นทอนความสามารถในการอ่านโค้ด

const ages = [10, 15, 20, 25];

const newAges = ages.map((age, index) => {
    if (index === 1) {
         return 16;
    }
    return age;
});

console.log(newAges); // [10, 16, 20, 25]
console.log(ages); // [10, 15, 20, 25] (Remains unchanged)

ต่อไปนี้คือตัวอย่าง Codepen ของวิธีใช้ .with() ใน React ร่วมกัน ร่วมกับ useState เพื่ออัปเดตอาร์เรย์ของรายการในทันที

เนื่องจากเมธอด .with() จะแสดงสำเนาของอาร์เรย์ คุณจึงสามารถเชื่อมโยง .with() การเรียกหรือแม้กระทั่งวิธีการอาร์เรย์อื่นๆ ตัวอย่างต่อไปนี้แสดง เพิ่มอายุที่ 2 และ 3 จากอาร์เรย์

const ages = [10, 15, 20, 25];

const newAges = ages.with(1, ages[1] + 1).with(2, ages[2] + 1)

console.log(newAges); // [10, 16, 21, 25]
console.log(ages); // [10, 15, 20, 25] (unchanged)

วิธีการใหม่อื่นๆ ที่เปลี่ยนแปลงไม่ได้

เมื่อเร็วๆ นี้ มีวิธีทำงานร่วมกันอีก 3 วิธีดังต่อไปนี้

  • Array.prototype.toReversed() ซึ่งจะกลับอาร์เรย์โดยไม่เปลี่ยนแปลง อาร์เรย์เดิม
  • Array.prototype.toSorted() ซึ่งจะจัดเรียงอาร์เรย์โดยไม่มี โดยเปลี่ยนรูปแบบอาร์เรย์เดิม
  • Array.prototype.toSpliced() ที่ทำงานคล้ายๆ กัน .splice() แต่ไม่เปลี่ยนแปลงอาร์เรย์ต้นฉบับ

ทั้ง 3 วิธีข้างต้นตามข้อมูลของ MDN คือเวอร์ชันที่คัดลอก ทั้ง 2 ส่วน นอกจากนี้ยังสามารถใช้วิธีการเหล่านี้ในกรณีที่คาดว่าจะเปลี่ยนแปลงไม่ได้ หรือ แนะนำ

กล่าวโดยสรุปคือ การอัปเดตที่เปลี่ยนแปลงไม่ได้นั้นทําได้ง่ายขึ้นใน JavaScript ที่มี 1 ใน 4 วิธีในบทความนี้ โดยเฉพาะอย่างยิ่ง เมธอด .with() ทำให้การอัปเดตเอลิเมนต์เดี่ยวของอาร์เรย์ง่ายขึ้น โดยไม่เปลี่ยนแปลงอาร์เรย์ต้นฉบับ