jquery.extend(true, [], obj) 不创建深层副本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16512773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jquery.extend(true, [], obj) not creating a deep copy
提问by Rose Perrone
If deep copying worked, the output would be "Curious George" and not "Ender's Game". How can I make a deep copy? An answer to this questionindicates that $.extend(true, [], obj)
creates a deep copy. Yet my example shows that it doesn't.
如果深度复制有效,输出将是“好奇的乔治”而不是“安德的游戏”。如何制作深拷贝?这个问题的答案表明$.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]);
SOLUTION
解决方案
I updated the jsFiddle. It turns out I need to deep copy each object in the array individually if the object is a custom object(that is, $.isPlainObject
returns false).
我更新了 jsFiddle。事实证明,如果对象是自定义对象(即$.isPlainObject
返回 false),我需要单独深度复制数组中的每个对象。
回答by zerkms
And now here is the realanswer:
现在这是真正的答案:
At the moment jQuery can only clone plain JavaScript Objects, while you're using custom ones. And that's obvious, since jQuery cannot know how exactly to instantiate a new custom object. So this works as expected:
目前 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);
Reference to a jQuery code: https://github.com/jquery/jquery/blob/master/src/core.js#L305
引用 jQuery 代码:https: //github.com/jquery/jquery/blob/master/src/core.js#L305
See that it checks if it's jQuery.isPlainObject(copy)
or it's an array. Otherwise it performs just a reference copy.
看到它检查它是jQuery.isPlainObject(copy)
还是一个数组。否则,它仅执行参考副本。
回答by Chtiwi Malek
This is how I've done it after trying many approaches:
在尝试了多种方法后,我是这样做的:
var newArray = JSON.parse(JSON.stringify(orgArray));
This will create a new deep copy, not a shallow copy.
这将创建一个新的深拷贝,而不是浅拷贝。
Also this obviously will not clone events and functions, but the good thing is you can do it in one line, and it can be used for any king of object (arrays, strings, numbers, objects, etc.).
此外,这显然不会克隆事件和函数,但好处是您可以在一行中完成,并且它可以用于任何对象之王(数组、字符串、数字、对象等)。
回答by Adam
Interesting....it doesn't look like it deep copies arrays.
有趣......它看起来不像是深度复制数组。
You have to deep copy each object individually.
您必须单独深度复制每个对象。
var people_copy = [];
$.each(people,function(i,obj) {
people_copy.push($.extend(true,{},obj));
});
EDIT: Sure, look at this fork of the OP's fiddle:
编辑:当然,看看 OP 小提琴的这个叉子: