structuredClone สำหรับสำเนาเชิงลึก
โคลนออบเจ็กต์ที่ซับซ้อนอย่างปลอดภัย
structuredClone สำหรับสำเนาเชิงลึก เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ปัญหาของสำเนาแบบลึก
การกระจายและ Object.assign สร้างสำเนาแบบตื้น: อ็อบเจ็กต์ที่ซ้อนกันจะใช้การอ้างอิงร่วมกัน หากต้องการทำสำเนาโครงสร้างที่ซ้อนกันทั้งหมด คุณต้องใช้สำเนาแบบลึก
structuredClone คือคำตอบที่มีอยู่ในตัวภาษา
เหตุใดการกระจายจึงไม่เพียงพอ
สำเนาจากการกระจายใช้อ็อบเจ็กต์ที่ซ้อนกันร่วมกัน การเปลี่ยนแปลงส่วนที่ซ้อนกันของสำเนาจึงส่งผลต่ออ็อบเจ็กต์ต้นฉบับด้วย
const original = { user: { name: 'Ada' } };
const shallow = { ...original };
shallow.user.name = 'Grace';
console.log(original.user.name);structuredClone เข้ามาช่วยแก้ปัญหา
structuredClone ทำสำเนาโครงสร้างทั้งหมดแบบเรียกซ้ำ การเปลี่ยนแปลงในสำเนาจะไม่แตะต้องอ็อบเจ็กต์ต้นฉบับ
const original = { user: { name: 'Ada' } };
const deep = structuredClone(original);
deep.user.name = 'Grace';
console.log(original.user.name);
console.log(deep.user.name);อ็อบเจ็กต์ที่ซ้อนกันเป็นอิสระต่อกัน
หลังจากทำสำเนา อ็อบเจ็กต์ที่ซ้อนกันแต่ละตัวจะมีการอ้างอิงแยกจากกัน ดังนั้นการเปรียบเทียบเอกลักษณ์จึงให้ค่าเป็นเท็จในทุกระดับ
const original = { a: { b: { c: 1 } } };
const clone = structuredClone(original);
console.log(original === clone);
console.log(original.a === clone.a);
console.log(original.a.b === clone.a.b);การทำสำเนาอาร์เรย์
อาร์เรย์ รวมถึงอาร์เรย์ที่ซ้อนกัน จะถูกทำสำเนาแบบลึกเช่นกัน การเพิ่มข้อมูลลงในอาร์เรย์ที่ซ้อนกันของสำเนาจึงไม่เปลี่ยนแปลงข้อมูลต้นทาง
const original = { tags: ['a', 'b'], meta: { nested: [1] } };
const clone = structuredClone(original);
clone.meta.nested.push(2);
console.log(original.meta.nested);
console.log(clone.meta.nested);รองรับ Map และ Set
ต่างจาก JSON.parse(JSON.stringify(...)) ตรงที่ structuredClone รองรับชนิดข้อมูลที่มีอยู่ในตัวภาษาหลายชนิด รวมถึง Map Set และ Date
const original = { items: new Set([1, 2, 3]), when: new Date(0) };
const clone = structuredClone(original);
clone.items.add(4);
console.log([...original.items]);
console.log([...clone.items]);
console.log(clone.when instanceof Date);รองรับการอ้างอิงแบบวนรอบ
อ็อบเจ็กต์ที่อ้างอิงตัวเองจะทำให้เทคนิค JSON ใช้ไม่ได้ แต่สามารถทำสำเนาได้อย่างถูกต้องด้วย structuredClone
const node = { name: 'root' };
node.self = node;
const clone = structuredClone(node);
console.log(clone.name);
console.log(clone.self === clone);สิ่งที่ไม่สามารถทำสำเนาได้
structuredClone ไม่สามารถคัดลอกฟังก์ชันหรือโหนด DOM ได้ และจะโยน DataCloneError นอกจากนี้ยังละทิ้งสายโซ่ต้นแบบ ทำให้ได้อ็อบเจ็กต์ธรรมดากลับมา
try {
structuredClone({ fn: () => 1 });
} catch (e) {
console.log(e.name);
}ต้นแบบจะไม่ถูกเก็บรักษาไว้
อินสแตนซ์ของคลาสที่ทำสำเนาจะกลายเป็นอ็อบเจ็กต์ธรรมดา โดยข้อมูลจะถูกคัดลอก แต่เมธอดและต้นแบบจะหายไป
class Point {
constructor(x) { this.x = x; }
show() { return this.x; }
}
const p = new Point(5);
const clone = structuredClone(p);
console.log(clone.x);
console.log(clone instanceof Point);structuredClone เทียบกับเทคนิค JSON
วิธีเดิมอย่าง JSON.parse(JSON.stringify(x)) จะทำข้อมูล undefined หายไป วันที่จะกลายเป็นสตริง และใช้ไม่ได้กับโครงสร้างที่วนรอบ ส่วน structuredClone หลีกเลี่ยงปัญหาเหล่านี้ได้สำหรับข้อมูลที่ทำให้เป็นอนุกรมได้
const data = { when: new Date(0), missing: undefined, n: 5 };
const viaJson = JSON.parse(JSON.stringify(data));
const viaClone = structuredClone(data);
console.log(typeof viaJson.when);
console.log(viaClone.when instanceof Date);เหตุใดเรื่องนี้จึงสำคัญ
structuredClone มอบวิธีทำสำเนาแบบลึกที่เชื่อถือได้และมีอยู่ในตัวภาษา สำหรับข้อมูลธรรมดา จึงใช้แทนการทำสำเนาเองที่เปราะบางได้ ใช้เมื่อคุณต้องการสำเนา state ที่ซ้อนกันและเป็นอิสระอย่างสมบูรณ์ และอย่าลืมว่าฟังก์ชันกับต้นแบบจะถูกตัดออก
const state = { list: [{ id: 1 }], settings: { theme: 'dark' } };
const snapshot = structuredClone(state);
snapshot.list[0].id = 99;
console.log(state.list[0].id);
console.log(snapshot.list[0].id);ตรวจสอบความเข้าใจอย่างรวดเร็ว
เหตุใดจึงควรใช้ structuredClone แทนตัวดำเนินการกระจายกับข้อมูลที่ซ้อนกัน
ทบทวน: structuredClone
คุณได้เรียนรู้การทำสำเนาแบบลึกที่เชื่อถือได้:
- การกระจายทำสำเนาแบบตื้น ส่วน
structuredCloneทำสำเนาแบบลึก - รองรับ
MapSetDateและการอ้างอิงแบบวนรอบ - ไม่สามารถทำสำเนาฟังก์ชันหรือโหนด DOM ได้ และจะละทิ้งต้นแบบ
- เป็นทางเลือกที่ปลอดภัยกว่าเทคนิค
JSON.parse(JSON.stringify())
คำถามที่พบบ่อย
บทเรียน “structuredClone สำหรับสำเนาเชิงลึก” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “structuredClone สำหรับสำเนาเชิงลึก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “structuredClone สำหรับสำเนาเชิงลึก”
โคลนออบเจ็กต์ที่ซับซ้อนอย่างปลอดภัย คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “structuredClone สำหรับสำเนาเชิงลึก” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม
ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Object.freeze และ seal
- การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก
- รูปแบบการอัปเดตแบบไม่เปลี่ยนแปลงข้อมูลเดิม
- structuredClone สำหรับสำเนาเชิงลึก