Shallow Copy vs Deep Copy ใน JavaScript
JavaScript จัดการการคัดลอกในสองรูปแบบ ขึ้นอยู่กับประเภทของข้อมูล
ค่าแบบ Primitive (Copy by Value) ประเภทข้อมูลแบบ Primitive ได้แก่ strings, numbers, booleans, symbols, bigInt และ null เมื่อคุณคัดลอกค่าแบบ primitive JavaScript จะสร้างเวอร์ชันใหม่ที่เป็นอิสระต่อกันในหน่วยความจำ
ตัวอย่าง: let a = 10; let b = a; b = 20; ผลลัพธ์: a ยังคงเป็น 10
ค่าแบบ Non-Primitive (Copy by Reference) Object และ array ทำงานแตกต่างออกไป โดยจะใช้การอ้างอิง (references) เมื่อคุณคัดลอก object คุณเพียงแค่คัดลอกตัวชี้ (pointer) ไปยังตำแหน่งของมันในหน่วยความจำเท่านั้น
ตัวอย่าง: let original = { name: "YOO" }; let copy = original; copy.name = "NEW"; ผลลัพธ์: original.name กลายเป็น "NEW" แล้ว
ความแตกต่าง: Shallow vs Deep
Shallow copy จะคัดลอกเฉพาะข้อมูลในระดับบนสุด (top level) ของ object เท่านั้น หาก object นั้นมี object ซ้อนอยู่ข้างใน (nested objects) มันจะยังคงชี้ไปยังการอ้างอิงเดิมของข้อมูลที่ซ้อนอยู่นั้น Deep copy จะสร้าง object ใหม่ขึ้นมาทั้งหมดพร้อมกับค่าใหม่ทั้งหมด
ลองนึกภาพเหมือนพิซซ่า:
- Shallow Copy: คุณและเพื่อนแชร์พิซซ่าถาดเดียวกัน ถ้าเพื่อนคุณกินไปหนึ่งชิ้น พิซซ่าของคุณก็จะเล็กลงด้วยเช่นกัน
- Deep Copy: คุณทั้งคู่มีพิซซ่าแยกกันคนละถาด ถ้าเพื่อนคุณกินไปหนึ่งชิ้น พิซซ่าของคุณก็ยังเหมือนเดิม
วิธีการทำ Shallow Copy คุณสามารถใช้ spread operator (...) เพื่อทำ shallow copy ได้
let original = { name: "YOO", details: { age: 22 } }; let copy = { ...original };
คำเตือน: หากคุณเปลี่ยนค่า original.details.age ค่า copy.details.age ก็จะเปลี่ยนตามไปด้วย นี่คือกับดักของการทำ shallow copy
วิธีการทำ Deep Copy
- structuredClone() นี่เป็นฟังก์ชันที่มีมาให้ในตัว (built-in) ในเบราว์เซอร์สมัยใหม่และ Node.js ซึ่งสามารถจัดการกับโครงสร้างข้อมูลที่ซ้อนกันได้อย่างสมบูรณ์แบบ
ข้อดี:
- รวดเร็วและเป็นแบบ native
- รองรับ Dates, RegExp และ Maps
ข้อเสีย:
- จะทำงานผิดพลาดหาก object นั้นมีฟังก์ชันหรือ DOM nodes อยู่ภายใน
- JSON.parse(JSON.stringify()) นี่เป็นเทคนิคเก่าแก่โดยการแปลง object ให้เป็น string แล้วแปลงกลับมาเป็น object อีกครั้ง
ทำไมถึงควรหลีกเลี่ยง:
- ข้อมูลบางอย่างจะหายไป เช่น undefined, Map, Set หรือ Infinity
- อาจทำให้ค่าบางอย่างผิดเพี้ยนไป
แหล่งที่มา: https://dev.to/yogesh_992/shallow-copy-vs-deep-copy-in-java-script-explained-in-easiest-way-3dg5
