Bạn không nên tạo các phần mở rộng của Nguyên mẫu, Điều này sẽ dẫn đến các vấn đề khi bạn thực hiện các thử nghiệm trên mã / thành phần của mình. Các khuôn khổ kiểm tra đơn vị sẽ không tự động giả định các phần mở rộng nguyên mẫu của bạn. Vì vậy, nó không phải là một thực hành tốt. Có nhiều lời giải thích hơn về các phần mở rộng nguyên mẫu tại đây Tại sao việc mở rộng các đối tượng gốc là một phương pháp không tốt?
Để sao chép các đối tượng trong JavaScript không có một cách đơn giản hay dễ hiểu. Đây là trường hợp đầu tiên sử dụng "Bản sao nông":
1 -> Phân thân nông:
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';
Các kết quả:
original.logFullName ():
kết quả: Cassio Seffrin
clone.logFullName ():
kết quả: John Seffrin
original.address.street;
result: 'Street B, 99' // thông báo rằng đối tượng con ban đầu đã được thay đổi
Lưu ý: Nếu cá thể có các bao đóng là thuộc tính riêng, phương thức này sẽ không bao bọc nó. ( đọc thêm về bao đóng ) Và thêm vào đó, đối tượng phụ "địa chỉ" sẽ không bị sao chép.
clone.logFullName ()
sẽ không làm việc.
cloneWithPrototype.logFullName ()
sẽ hoạt động, vì bản sao cũng sẽ sao chép Nguyên mẫu của nó.
Để sao chép mảng với Object.assign:
let cloneArr = array.map((a) => Object.assign({}, a));
Sao chép mảng sử dụng sintax trải rộng ECMAScript:
let cloneArrSpread = array.map((a) => ({ ...a }));
2 -> Nhân bản sâu:
Để lưu trữ một tham chiếu đối tượng hoàn toàn mới, chúng ta có thể sử dụng JSON.stringify () để phân tích cú pháp đối tượng ban đầu dưới dạng chuỗi và sau khi phân tích cú pháp nó trở lại JSON.parse ().
let deepClone = JSON.parse(JSON.stringify(original));
Với bản sao sâu, các tham chiếu đến địa chỉ sẽ được lưu giữ. Tuy nhiên, các Nguyên mẫu deepClone sẽ bị đóng, do đó deepClone.logFullName () sẽ không hoạt động.
Thư viện bên thứ 3 ->:
Một tùy chọn khác sẽ là sử dụng thư viện của bên thứ 3 như loadash hoặc gạch dưới. Họ sẽ tạo một đối tượng mới và sao chép từng giá trị từ bản gốc sang đối tượng mới, giữ các tham chiếu của nó trong bộ nhớ.
Dấu gạch dưới: let cloneUnderscore = _ (original) .clone ();
Loadash bản sao: var cloneLodash = _.cloneDeep (bản gốc);
Nhược điểm của lodash hoặc gạch dưới là cần phải bao gồm một số thư viện bổ sung trong dự án của bạn. Tuy nhiên chúng là những lựa chọn tốt và cũng tạo ra kết quả hiệu suất cao.