การแก้ปัญหาเฉพาะ
คุณสามารถใช้การยืนยันประเภทเพื่อบอกคอมไพเลอร์ว่าคุณรู้ดีกว่า:
public clone(): any {
var cloneObj = new (this.constructor() as any);
for (var attribut in this) {
if (typeof this[attribut] === "object") {
cloneObj[attribut] = this[attribut].clone();
} else {
cloneObj[attribut] = this[attribut];
}
}
return cloneObj;
}
โคลน
โปรดจำไว้ว่าบางครั้งการเขียนแผนที่ของคุณจะดีกว่าการทำแผนที่แบบไดนามิก อย่างไรก็ตามมีเทคนิค "การโคลนนิ่ง" บางอย่างที่คุณสามารถใช้เพื่อให้เอฟเฟกต์ต่างกัน
ฉันจะใช้รหัสต่อไปนี้สำหรับตัวอย่างที่ตามมาทั้งหมด:
class Example {
constructor(public type: string) {
}
}
class Customer {
constructor(public name: string, public example: Example) {
}
greet() {
return 'Hello ' + this.name;
}
}
var customer = new Customer('David', new Example('DavidType'));
ตัวเลือกที่ 1: การแพร่กระจาย
คุณสมบัติ: ใช่
วิธีการ: ไม่
คัดลอกลึก: ไม่
var clone = { ...customer };
alert(clone.name + ' ' + clone.example.type); // David DavidType
//alert(clone.greet()); // Not OK
clone.name = 'Steve';
clone.example.type = 'SteveType';
alert(customer.name + ' ' + customer.example.type); // David SteveType
ตัวเลือก 2: Object.assign
คุณสมบัติ: ใช่
วิธีการ: ไม่
คัดลอกลึก: ไม่
var clone = Object.assign({}, customer);
alert(clone.name + ' ' + clone.example.type); // David DavidType
alert(clone.greet()); // Not OK, although compiler won't spot it
clone.name = 'Steve';
clone.example.type = 'SteveType';
alert(customer.name + ' ' + customer.example.type); // David SteveType
ตัวเลือก 3: Object.create
คุณสมบัติ:
วิธีการรับช่วง
: รับ
สำเนาลึก: สืบทอดตื้น (การเปลี่ยนแปลงที่ลึกส่งผลกระทบต่อทั้งต้นฉบับและโคลน)
var clone = Object.create(customer);
alert(clone.name + ' ' + clone.example.type); // David DavidType
alert(clone.greet()); // OK
customer.name = 'Misha';
customer.example = new Example("MishaType");
// clone sees changes to original
alert(clone.name + ' ' + clone.example.type); // Misha MishaType
clone.name = 'Steve';
clone.example.type = 'SteveType';
// original sees changes to clone
alert(customer.name + ' ' + customer.example.type); // Misha SteveType
ตัวเลือก 4: ฟังก์ชั่นการทำสำเนาลึก
คุณสมบัติ: ใช่
วิธีการ: ไม่
คัดลอกลึก: ใช่
function deepCopy(obj) {
var copy;
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;
// Handle Date
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = deepCopy(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = deepCopy(obj[attr]);
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
var clone = deepCopy(customer) as Customer;
alert(clone.name + ' ' + clone.example.type); // David DavidType
// alert(clone.greet()); // Not OK - not really a customer
clone.name = 'Steve';
clone.example.type = 'SteveType';
alert(customer.name + ' ' + customer.example.type); // David DavidType