…每个对象在同一个数组中也有对其他对象的引用?
当我第一次想到这个问题的时候,我就想到了
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中是否有可重用的方法来做到这一点?
如果你只需要一个浅克隆,最好的方法如下:
使用…ES6扩展运算符。
这里有一个最简单的例子:
var clonedObjArray = [...oldObjArray];
通过这种方式,我们将数组扩展为单独的值,并使用[]操作符将其放入一个新数组中。
下面是一个更长的例子,展示了它的不同工作方式:
let objArray = [ {a:1} , {b:2} ];
let refArray = objArray; // this will just point to the objArray
let clonedArray = [...objArray]; // will clone the array
console.log( "before:" );
console.log( "obj array" , objArray );
console.log( "ref array" , refArray );
console.log( "cloned array" , clonedArray );
objArray[0] = {c:3};
console.log( "after:" );
console.log( "obj array" , objArray ); // [ {c:3} , {b:2} ]
console.log( "ref array" , refArray ); // [ {c:3} , {b:2} ]
console.log( "cloned array" , clonedArray ); // [ {a:1} , {b:2} ]
我之所以回答这个问题,是因为似乎没有一个简单而明确的解决方案来解决“在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()对于数组中的对象是不够的。