Có một số vấn đề với hầu hết các giải pháp trên Internet. Vì vậy, tôi quyết định thực hiện theo dõi, bao gồm, tại sao câu trả lời được chấp nhận không nên được chấp nhận.
bắt đầu tình huống
Tôi muốn kết hợp sâu sắc một JavaScript
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
4 với tất cả trẻ em và con cái của họ, v.v. Nhưng vì tôi không phải là nhà phát triển bình thường, var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
4 của tôi có bình thường var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
6, var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
7 và thậm chí var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
8.deep-copy a Javascript var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
4 with all of its children and their children and so on. But since I'm not kind of a normal developer, my var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
4 has normal var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
6, var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
7 and even var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
8.Vì vậy, hãy tạo một
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
9 và var b = a;
b.x = 'b';
b.nested.y = 'b';
0 trước.function Circ[] {
this.me = this;
}
function Nested[y] {
this.y = y;
}
Hãy mang mọi thứ lại với nhau trong một
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
4 có tên var b = a;
b.x = 'b';
b.nested.y = 'b';
2.var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
Tiếp theo, chúng tôi muốn sao chép
var b = a;
b.x = 'b';
b.nested.y = 'b';
2 vào một biến có tên var b = a;
b.x = 'b';
b.nested.y = 'b';
4 và biến đổi nó.var b = a;
b.x = 'b';
b.nested.y = 'b';
Bạn biết những gì đã xảy ra ở đây bởi vì nếu không bạn thậm chí sẽ không đáp ứng câu hỏi tuyệt vời này.
console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
Bây giờ chúng ta hãy tìm một giải pháp.
Json
Nỗ lực đầu tiên tôi đã thử là sử dụng
var b = a;
b.x = 'b';
b.nested.y = 'b';
5.var b = JSON.parse[ JSON.stringify[ a ] ];
b.x = 'b';
b.nested.y = 'b';
Đừng lãng phí quá nhiều thời gian cho nó, bạn sẽ nhận được
var b = a;
b.x = 'b';
b.nested.y = 'b';
6.Bản sao đệ quy ["câu trả lời" được chấp nhận
Chúng ta hãy xem câu trả lời được chấp nhận.
function cloneSO[obj] {
// Handle the 3 simple types, and null or undefined
if [null == obj || "object" != typeof obj] return obj;
// Handle Date
if [obj instanceof Date] {
var copy = new Date[];
copy.setTime[obj.getTime[]];
return copy;
}
// Handle Array
if [obj instanceof Array] {
var copy = [];
for [var i = 0, len = obj.length; i < len; i++] {
copy[i] = cloneSO[obj[i]];
}
return copy;
}
// Handle Object
if [obj instanceof Object] {
var copy = {};
for [var attr in obj] {
if [obj.hasOwnProperty[attr]] copy[attr] = cloneSO[obj[attr]];
}
return copy;
}
throw new Error["Unable to copy obj! Its type isn't supported."];
}
Có vẻ tốt, heh? Đó là một bản sao đệ quy của đối tượng và cũng xử lý các loại khác, như
var b = a;
b.x = 'b';
b.nested.y = 'b';
7, nhưng đó không phải là một yêu cầu.var b = cloneSO[a];
b.x = 'b';
b.nested.y = 'b';
Đệ quy và
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
7 không hoạt động tốt với nhau ... var b = a;
b.x = 'b';
b.nested.y = 'b';
9Giải pháp gốc
Sau khi tranh cãi với đồng nghiệp của tôi, ông chủ của tôi đã hỏi chúng tôi chuyện gì đã xảy ra, và anh ấy đã tìm thấy một giải pháp đơn giản sau một số googling. Nó được gọi là
console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
0.var b = Object.create[a];
b.x = 'b';
b.nested.y = 'b';
Giải pháp này đã được thêm vào JavaScript một thời gian trước và thậm chí xử lý
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
9.console.log[a, b];
a --> Object {
x: "a",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
... Và bạn thấy đấy, nó không hoạt động với cấu trúc lồng nhau bên trong.
polyfill cho giải pháp gốc
Có một polyfill cho
console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
0 trong trình duyệt cũ giống như IE 8. Nó giống như một cái gì đó được đề xuất bởi Mozilla, và tất nhiên, nó không hoàn hảo và dẫn đến vấn đề tương tự như giải pháp gốc.function F[] {};
function clonePF[o] {
F.prototype = o;
return new F[];
}
var b = clonePF[a];
b.x = 'b';
b.nested.y = 'b';
Tôi đã đặt
console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
3 ngoài phạm vi để chúng ta có thể xem xét những gì console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
4 nói với chúng ta.var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
0Vấn đề tương tự như giải pháp gốc, nhưng đầu ra tồi tệ hơn một chút.
Giải pháp tốt hơn [nhưng không hoàn hảo]
Khi đào xung quanh, tôi tìm thấy một câu hỏi tương tự [trong JavaScript, khi thực hiện một bản sao sâu, làm thế nào để tôi tránh một chu kỳ, do một tài sản là "cái này"?] Cho cái này, nhưng với một giải pháp tốt hơn.
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
1Và chúng ta hãy xem đầu ra ...
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
2Các yêu cầu được khớp, nhưng vẫn còn một số vấn đề nhỏ hơn, bao gồm thay đổi
console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
5 của console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
6 và console.log[a, b];
a --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
b --> Object {
x: "b",
circ: Circ {
me: Circ { ... }
},
nested: Nested {
y: "b"
}
}
7 thành var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
4.Cấu trúc của những cây có chung một chiếc lá sẽ không được sao chép, chúng sẽ trở thành hai lá độc lập:
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
3phần kết luận
Giải pháp cuối cùng sử dụng đệ quy và bộ nhớ cache, có thể không phải là tốt nhất, nhưng đó là một bản sao sâu thực sự của đối tượng. Nó xử lý đơn giản
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
6, var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
7 và var b = a;
b.x = 'b';
b.nested.y = 'b';
0, nhưng nó sẽ làm rối loạn chúng trong khi nhân bản.real deep-copy of the object. It handles simple
var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
6, var a = {
x: 'a',
circ: new Circ[],
nested: new Nested['a']
};
7 and var b = a;
b.x = 'b';
b.nested.y = 'b';
0, but it will mess up the instance of them while cloning.JSfiddle