Deep Clone วัตถุใน JavaScript
Deep Clone ของออบเจกต์คือออบเจ็กต์ใหม่ที่มีสำเนาของคุณสมบัติทั้งหมดแยกจากกันโดยสิ้นเชิง รวมถึงออบเจ็กต์ที่ซ้อนกัน สิ่งนี้แตกต่างจากการโคลนนิ่งแบบตื้นซึ่งเฉพาะคุณสมบัติระดับแรกเท่านั้นที่จะถูกคัดลอกและอ้างอิงวัตถุที่ซ้อนกันแทนที่จะคัดลอก
มีหลายวิธีในการทำ Deep Clone ของวัตถุใน JavaScript แต่มีเพียงวิธีเดียวที่ดีที่สุด
เราสามารถใช้ JSON.parse & JSON.stringify ได้หรือไม่ ❌
JSON.parse(JSON.stringify(obj)) — วิธีนี้ใช้การทำให้เป็นอนุกรม JSON เพื่อสร้างการโคลนลึกของวัตถุ ใช้ได้กับวัตถุที่ไม่มีการอ้างอิงแบบวงกลม แต่จะล้มเหลวหากวัตถุมีการอ้างอิงแบบวงกลม
const obj = { a: 1, b: { c: 2 } };
const clone = JSON.parse(JSON.stringify(obj));
console.log(clone);
// Output: { a: 1, b: { c: 2 } }
ใช้สิ่งนี้เป็นตัวอย่าง:
แหล่งที่มา:https://www.builder.io/blog/structured-clone
const calendarEvent = {
title: "source: https://www.builder.io/blog/structured-clone",
date: new Date(123),
attendees: ["Lian"]
}
// JSON.stringify converted the `date` to a string
const copy = JSON.parse(JSON.stringify(calendarEvent))
{
title: "source: https://www.builder.io/blog/structured-clone",
date: "1970-01-01T00:00:00.123Z"
attendees: ["Lian"]
}
เราสามารถใช้ Lodash หรือขีดล่าง _.cloneDeep() วิธีการได้หรือไม่ ❌ (ไม่ต้องการ)
แหล่งที่มา:https://www.builder.io/blog/structured-clone
วิธี Lodash หรือขีดล่าง _.cloneDeep() — ไลบรารีเหล่านี้มีฟังก์ชันการโคลนแบบลึกที่สามารถจัดการการอ้างอิงแบบวงกลมและกรณีขอบอื่นๆ
const _ = require('lodash');
const obj = { a: 1, b: { c: 2 } };
const clone = _.cloneDeep(obj);
console.log(clone);
// Output: { a: 1, b: { c: 2 } }
และอันที่จริงแล้วสิ่งนี้ทำงานได้ตามที่คาดไว้:
import cloneDeep from 'lodash/cloneDeep'
const calendarEvent = {
title: "source: https://www.builder.io/blog/structured-clone",
date: new Date(123),
attendees: ["Lian"]
}
// ✅ All good!
const clonedEvent = structuredClone(calendarEvent)
ขนาดโดยประมาณนี้ขึ้นอยู่กับการนำเข้าฟังก์ชันทีละรายการเท่านั้น หากคุณเลือกวิธีการนำเข้าที่ใช้กันโดยทั่วไป โดยไม่ได้พิจารณาว่าการสั่นของต้นไม้อาจไม่ได้ผลเสมอไป คุณอาจลงเอยด้วยการนำเข้าข้อมูลมากถึง 25kb สำหรับฟังก์ชันเดียวนี้เท่านั้น
แม้ว่าข้อมูลจำนวนนี้จะไม่มีนัยสำคัญ แต่ก็ไม่จำเป็นในสถานการณ์ของเรา เนื่องจากเบราว์เซอร์สมัยใหม่มีคุณลักษณะของ Structured Clone ในตัวอยู่แล้ว
เราสามารถใช้ตัวดำเนินการสเปรดเพื่อโคลนวัตถุในระดับลึกได้หรือไม่? ❌
ไม่ ตัวดำเนินการสเปรด ( ...) ใน JavaScript จะทำการโคลนวัตถุแบบตื้นๆ เท่านั้น เมื่อใช้โอเปอเรเตอร์สเปรดเพื่อโคลนวัตถุ วัตถุที่ซ้อนกันจะยังคงถูกอ้างอิงแทนที่จะคัดลอก ดังนั้นการเปลี่ยนแปลงวัตถุที่ซ้อนกันในวัตถุที่โคลนจะส่งผลต่อวัตถุดั้งเดิมด้วย
นี่คือตัวอย่าง:
const original = {a: 1, b: {c: 2}};
const clone = {...original};
console.log(clone);
// Output: {a: 1, b: {c: 2}}
clone.b.c = 3;
console.log(original);
// Output: {a: 1, b: {c: 3}}
เราสามารถใช้ Object.assign เพื่อโคลนวัตถุในจาวาสคริปต์ได้หรือไม่? ❌
ไม่Object.assign()เมธอดใน JavaScript จะทำการโคลนอ็อบเจกต์แบบตื้นๆ เท่านั้น เมื่อใช้Object.assign()เพื่อโคลนวัตถุ วัตถุที่ซ้อนกันจะยังคงถูกอ้างอิงแทนที่จะคัดลอก ดังนั้นการเปลี่ยนแปลงวัตถุที่ซ้อนกันในวัตถุที่โคลนจะส่งผลต่อวัตถุต้นฉบับด้วย
นี่คือตัวอย่าง:
const original = {a: 1, b: {c: 2}};
const clone = Object.assign({}, original);
console.log(clone);
// Output: {a: 1, b: {c: 2}}
clone.b.c = 3;
console.log(original);
// Output: {a: 1, b: {c: 3}}
โครงสร้างโคลน✅
เป็นstructured cloneแนวคิดใน JavaScript ที่อ้างถึงกระบวนการสร้าง Deep Clone ของออบเจกต์ รวมถึงอ็อบเจ็กต์และอาร์เรย์ที่ซ้อนกัน ตลอดจนโครงสร้างข้อมูลที่ซับซ้อนอื่นๆ อัลกอริทึม นี้structured cloneถูกใช้โดย API หลายตัวใน JavaScript เช่นpostMessageวิธีการสื่อสารระหว่างวัตถุหน้าต่าง (เช่น ระหว่างเพจกับ iframe) API IndexedDBสำหรับจัดเก็บและดึงข้อมูลในเบราว์เซอร์ และService WorkersAPI สำหรับการประมวลผลพื้นหลังของคำขอเครือข่าย
อัstructured cloneลกอริทึมทำงานโดยการคัดลอกคุณสมบัติทั้งหมดของออบเจกต์ซ้ำๆ รวมถึงออบเจกต์ที่ซ้อนกันและอาร์เรย์ ลงในออบเจ็กต์ใหม่ที่มีโครงสร้างและค่าเดียวกัน สามารถจัดการประเภทข้อมูลได้หลากหลาย รวมถึงฟังก์ชัน วันที่ นิพจน์ทั่วไป อาร์เรย์ และออบเจกต์
อัstructured cloneลกอริทึมเป็นเครื่องมือที่ทรงพลังสำหรับการสร้างโคลนเชิงลึกของโครงสร้างข้อมูลที่ซับซ้อนใน JavaScript และมักใช้เพื่อดำเนินการที่ซับซ้อนกับข้อมูลในเบราว์เซอร์หรือสภาพแวดล้อม JavaScript อื่นๆ
การใช้งานแบบกำหนดเองโดยใช้การเรียกซ้ำ — วิธีนี้เกี่ยวข้องกับการกำหนดฟังก์ชันที่ใช้การเรียกซ้ำเพื่อสร้างการโคลนลึกของวัตถุ
const original = { a: 1, b: { c: new Date() } };
const deepClone = (obj) => {
if (obj === null || typeof obj !== "object") return obj;
let clone = Array.isArray(obj) ? [] : {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] =
obj[key] instanceof Date
? new Date(obj[key].getTime())
: deepClone(obj[key]);
}
}
return clone;
};
const clone = deepClone(original);
console.log(clone);
// Output: {a: 1, b: {c: 2022-12-31T08:00:00.000Z}}
clone.b.c.setFullYear(2023);
console.log(original);
// Output: {a: 1, b: {c: 2022-12-31T08:00:00.000Z}}





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)