…每个对象在同一个数组中也有对其他对象的引用?
当我第一次想到这个问题的时候,我就想到了
var clonedNodesArray = nodesArray.clone()
并搜索如何在JavaScript中克隆对象的信息。我确实在Stack Overflow上找到了一个问题(同样由@JohnResig回答),他指出用jQuery你可以做到
var clonedNodesArray = jQuery.extend({}, nodesArray);
克隆对象。虽然我尝试了这个,但这只复制了数组中对象的引用。如果我
nodesArray[0].value = "red"
clonedNodesArray[0].value = "green"
nodesArray[0]和clonedNodesArray[0]的值将显示为“绿色”。然后我尝试了
var clonedNodesArray = jQuery.extend(true, {}, nodesArray);
它深度复制了一个对象,但我分别从Firebug和Opera Dragonfly得到了“太多递归”和“控制堆栈溢出”的消息。
你会怎么做?这是不应该做的事情吗?在JavaScript中是否有可重用的方法来做到这一点?
我之所以回答这个问题,是因为似乎没有一个简单而明确的解决方案来解决“在JavaScript中克隆对象数组”的问题:
function deepCopy (arr) {
var out = [];
for (var i = 0, len = arr.length; i < len; i++) {
var item = arr[i];
var obj = {};
for (var k in item) {
obj[k] = item[k];
}
out.push(obj);
}
return out;
}
// test case
var original = [
{'a' : 1},
{'b' : 2}
];
var copy = deepCopy(original);
// change value in copy
copy[0]['a'] = 'not 1';
// original[0]['a'] still equals 1
该解决方案迭代数组值,迭代对象键,将后者保存到一个新对象,并将该新对象推入到一个新数组。
看到jsfiddle。注意:简单的.slice()或[].concat()对于数组中的对象是不够的。
这个问题让我很沮丧。显然,当你发送一个泛型数组到$。扩展方法。因此,为了解决这个问题,我添加了一个小检查,它可以完美地与通用数组、jQuery数组和任何对象一起工作。
jQuery.extend({
deepclone: function(objThing) {
// return jQuery.extend(true, {}, objThing);
/// Fix for arrays, without this, arrays passed in are returned as OBJECTS! WTF?!?!
if ( jQuery.isArray(objThing) ) {
return jQuery.makeArray( jQuery.deepclone($(objThing)) );
}
return jQuery.extend(true, {}, objThing);
},
});
调用使用:
var arrNewArrayClone = jQuery.deepclone(arrOriginalArray);
// Or more simply/commonly
var arrNewArrayClone = $.deepclone(arrOriginalArray);
我之所以回答这个问题,是因为似乎没有一个简单而明确的解决方案来解决“在JavaScript中克隆对象数组”的问题:
function deepCopy (arr) {
var out = [];
for (var i = 0, len = arr.length; i < len; i++) {
var item = arr[i];
var obj = {};
for (var k in item) {
obj[k] = item[k];
}
out.push(obj);
}
return out;
}
// test case
var original = [
{'a' : 1},
{'b' : 2}
];
var copy = deepCopy(original);
// change value in copy
copy[0]['a'] = 'not 1';
// original[0]['a'] still equals 1
该解决方案迭代数组值,迭代对象键,将后者保存到一个新对象,并将该新对象推入到一个新数组。
看到jsfiddle。注意:简单的.slice()或[].concat()对于数组中的对象是不够的。