Giải quyết vấn đề cụ thể
Bạn có thể sử dụng một xác nhận kiểu để nói với trình biên dịch mà bạn biết rõ hơn:
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;
}
Nhân bản
Hãy nhớ rằng đôi khi tốt hơn là viết bản đồ của riêng bạn - thay vì hoàn toàn năng động. Tuy nhiên, có một vài thủ thuật "nhân bản" mà bạn có thể sử dụng mang lại cho bạn hiệu ứng khác biệt.
Tôi sẽ sử dụng mã sau đây cho tất cả các ví dụ sau:
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'));
Cách 1: Lan truyền
Thuộc tính: Có
Phương thức: Không
Sao chép sâu: Không
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
Tùy chọn 2: Object.assign
Thuộc tính: Có
Phương thức: Không
Sao chép sâu: Không
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
Tùy chọn 3: Object.create
Thuộc tính: Kế thừa
Phương pháp: Kế thừa
Sâu Copy: Shallow thừa kế (thay đổi sâu sắc ảnh hưởng đến cả bản gốc và bản sao)
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
Tùy chọn 4: Chức năng sao chép sâu
Thuộc tính: Có
Phương thức: Không
Sao chép sâu: Có
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