16

jsFiddle 在这里

如果深度复制有效,输出将是“Curious George”而不是“Ender's Game”。如何制作深拷贝?这个问题的答案表明$.extend(true, [], obj)创建了一个深层副本。然而我的例子表明它没有。

function Person(){}
Person.prototype.favorite_books = [];

var george = new Person();
george.favorite_books = ["Curious George"];

var kate = new Person();
kate.favorite_books = ["The Da Vinci Code", "Harry Potter"];

var people = [kate, george];

var people_copy = $.extend(true, [], people);
people_copy[0].favorite_books[0] = "Ender's Game";

$('#text').text(people[0].favorite_books[0]);

解决方案

我更新了 jsFiddle。事实证明,如果对象是自定义对象(即$.isPlainObject返回 false),我需要单独深度复制数组中的每个对象。

4

3 回答 3

21

现在这是真正的答案:

目前 jQuery 只能克隆纯 JavaScript 对象,而您使用的是自定义对象。这很明显,因为 jQuery 不知道如何准确地实例化一个新的自定义对象。所以这可以按预期工作:

var george = {};
george.favorite_books = ["Curious George"];

var kate = {};
kate.favorite_books = ["The Da Vinci Code", "Harry Potter"];

var people = [kate, george];

var people_copy = $.extend(true, [], people);

console.log(people_copy[0].favorite_books == people[0].favorite_books);

引用一个 jQuery 代码:https ://github.com/jquery/jquery/blob/master/src/core.js#L305

看看它检查它是否jQuery.isPlainObject(copy)是一个数组。否则它只执行一个参考副本。

于 2013-05-12T23:00:36.147 回答
8

这就是我在尝试了许多方法后所做的:

var newArray = JSON.parse(JSON.stringify(orgArray));

这将创建一个新的深拷贝,而不是浅拷贝。

同样,这显然不会克隆事件和函数,但好处是您可以在一行中完成,它可以用于任何对象之王(数组、字符串、数字、对象等)。

于 2014-04-23T13:36:53.857 回答
4

有趣....它看起来不像是深拷贝数组。

您必须单独深度复制每个对象。

var people_copy = [];
$.each(people,function(i,obj) {
    people_copy.push($.extend(true,{},obj)); 
});

编辑:当然,看看 OP 小提琴的这个分支:

http://jsfiddle.net/s2bLv/4/

于 2013-05-12T22:49:08.060 回答