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

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

การสนับสนุนเบราว์เซอร์

  • 110
  • 110
  • 115
  • 16

แหล่งที่มา

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

ข้อมูลเบื้องต้นเกี่ยวกับ 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 จะไม่คัดลอกอาร์เรย์ แต่จะสร้างการอ้างอิงไปยังอาร์เรย์อื่น ดังนั้นการเปลี่ยนแปลงอันใดอันหนึ่งจะกระทบกับอีกอันหนึ่งด้วย เพราะการเปลี่ยนแปลงทั้งคู่ชี้ไปยังอาร์เรย์เดียวกัน

Array.proftype.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() แต่ไม่เปลี่ยนแปลงอาร์เรย์เดิม

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

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