…每个对象在同一个数组中也有对其他对象的引用?

当我第一次想到这个问题的时候,我就想到了

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中是否有可重用的方法来做到这一点?


当前回答

在我的例子中,我有一个包含许多嵌套对象的数组,所以其他答案不适用于我的用例。

我现在使用的是npm包deep-copy-all:

npm i deep-copy-all
const deepCopy = require("deep-copy-all")

const copy = deepCopy(original)
copy[0].users[0].payments[0].product.price = 10

console.log(copy[0].users[0].payments[0].product.price) // 10
console.log(original[0].users[0].payments[0].product.price) // 5

其他回答

最简洁的浅拷贝解决方案:

array = array.map(obj => {
    return { ...obj };
});

这将生成[{a: 1}, {b: 2}]等内容的完全独立副本,而不是[{a: {b: 2}}, {b: {a: 1}}]。

JavaScript中深度克隆的一些优雅方法:

对象类型: 用JavaScript复制对象

 

用于克隆对象的普通JavaScript方法 巧妙地利用JSON库对对象进行深度克隆 使用jQuery的$.extend()函数 使用Mootools的clone()函数克隆对象

我之所以回答这个问题,是因为似乎没有一个简单而明确的解决方案来解决“在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()对于数组中的对象是不够的。

如何使用一个简单的递归函数来获得对象/数组的深层副本

const deepCopyFunction = (inObject) => { const deepCopyObject = Array.isArray(inObject) ?[]: {}; for (inObject中的const键){ if (typeof inObject[key] === 'object') { deepCopyFunction (inObject(例子)); } deepCopyObject[key] = inObject[key]; } 返回deepCopyObject; }

数组中。Slice可以用来复制一个数组或数组的一部分…

这将与字符串和数字工作..-改变一个数组中的字符串不会影响另一个数组-但对象仍然只是通过引用复制,所以改变一个数组中引用的对象会影响另一个数组。

下面是一个JavaScript撤销管理器的示例,它可能对此很有用:http://www.ridgway.co.za/archive/2007/11/07/simple-javascript-undo-manager-for-dtos.aspx