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

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

Browser Support

  • Chrome: 110.
  • Edge: 110.
  • Firefox: 115.
  • Safari: 16.

Source

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

ข้อมูลเบื้องต้นเกี่ยวกับ Array.prototype.with(index, value)

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

ตัวอย่างต่อไปนี้แสดงอาร์เรย์ของอายุ คุณต้องการสร้างสำเนาใหม่ของอาร์เรย์ ขณะเปลี่ยนอายุที่ 2 จาก 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.prototype.with() และความไม่เปลี่ยนรูป

ความไม่เปลี่ยนแปลงเป็นหัวใจสำคัญของไลบรารีและเฟรมเวิร์กส่วนหน้าหลายรายการ เช่น React (และ Redux) และ 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() แต่จะไม่เปลี่ยนแปลงอาร์เรย์ต้นฉบับ

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

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