ไม่แนะนำให้สร้างส่วนขยายของ Prototype ซึ่งจะทำให้เกิดปัญหาเมื่อคุณทำการทดสอบโค้ด / ส่วนประกอบของคุณ กรอบการทดสอบหน่วยจะไม่ถือว่าส่วนขยายต้นแบบของคุณโดยอัตโนมัติ ดังนั้นจึงไม่ใช่แนวทางปฏิบัติที่ดี มีคำอธิบายเพิ่มเติมเกี่ยวกับส่วนขยายต้นแบบที่นี่เหตุใดการขยายวัตถุดั้งเดิมจึงเป็นการปฏิบัติที่ไม่ดี
ในการโคลนวัตถุใน JavaScript ไม่มีวิธีที่ง่ายหรือตรงไปตรงมา นี่คือตัวอย่างแรกที่ใช้ "Shallow Copy":
1 -> โคลนตื้น:
class Employee {
constructor(first, last, street) {
this.firstName = first;
this.lastName = last;
this.address = { street: street };
}
logFullName() {
console.log(this.firstName + ' ' + this.lastName);
}
}
let original = new Employee('Cassio', 'Seffrin', 'Street A, 23');
let clone = Object.assign({},original);
let cloneWithPrototype Object.create(Object.getPrototypeOf(original)), original)
let clone2 = { ...original };
clone.firstName = 'John';
clone.address.street = 'Street B, 99';
ผล:
original.logFullName ():
ผลลัพธ์: Cassio Seffrin
clone.logFullName ():
ผลลัพธ์: John Seffrin
original.address.street;
ผลลัพธ์: 'Street B, 99' // สังเกตว่าวัตถุย่อยดั้งเดิมมีการเปลี่ยนแปลง
หมายเหตุ: หากอินสแตนซ์มีการปิดเป็นคุณสมบัติของตัวเองวิธีนี้จะไม่รวมเข้าด้วยกัน ( อ่านเพิ่มเติมเกี่ยวกับการปิด ) และนอกจากนี้วัตถุย่อย "ที่อยู่" จะไม่ถูกโคลน
clone.logFullName ()
จะไม่ทำงาน.
cloneWithPrototype.logFullName ()
จะใช้งานได้เพราะโคลนจะคัดลอก Prototypes ไปด้วย
ในการโคลนอาร์เรย์ด้วย Object.assign:
let cloneArr = array.map((a) => Object.assign({}, a));
โคลนอาร์เรย์โดยใช้ ECMAScript spread sintax:
let cloneArrSpread = array.map((a) => ({ ...a }));
2 -> โคลนลึก:
ในการเก็บการอ้างอิงอ็อบเจ็กต์ใหม่ทั้งหมดเราสามารถใช้ JSON.stringify () เพื่อแยกวิเคราะห์ออบเจ็กต์ดั้งเดิมเป็นสตริงและหลังจากแยกวิเคราะห์กลับเป็น JSON.parse ()
let deepClone = JSON.parse(JSON.stringify(original));
ด้วยการโคลนลึกการอ้างอิงไปยังที่อยู่จะถูกเก็บไว้ อย่างไรก็ตาม deepClone Prototypes จะหายไปดังนั้น deepClone.logFullName () จะไม่ทำงาน
3 -> ห้องสมุดบุคคลที่ 3:
อีกทางเลือกหนึ่งคือใช้ไลบรารีของบุคคลที่ 3 เช่น loadash หรือขีดล่าง พวกเขาจะสร้างวัตถุใหม่และคัดลอกแต่ละค่าจากต้นฉบับไปยังวัตถุใหม่โดยเก็บข้อมูลอ้างอิงไว้ในหน่วยความจำ
ขีดล่าง: ให้ cloneUnderscore = _ (ต้นฉบับ) .clone ();
Loadash clone: var cloneLodash = _.cloneDeep (ต้นฉบับ);
ข้อเสียของ lodash หรือขีดล่างคือจำเป็นต้องรวมไลบรารีเพิ่มเติมไว้ในโครงการของคุณ อย่างไรก็ตามเป็นตัวเลือกที่ดีและยังให้ผลลัพธ์ที่มีประสิทธิภาพสูงอีกด้วย