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

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

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


当前回答

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

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

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

其他回答

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

我现在使用的是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

正如Daniel Lew提到的,循环图有一些问题。如果我有这个问题,我要么向有问题的对象添加特殊的clone()方法,要么记住我已经复制了哪些对象。

我会用一个变量copyCount来做,它在你每次复制代码时增加1。copyCount小于当前复制进程的对象将被复制。如果不是,则应该引用已经存在的副本。这就需要从原文链接到副本。

还有一个问题:内存。如果您从一个对象引用到另一个对象,那么浏览器很可能无法释放这些对象,因为它们总是从某个地方引用。您必须进行第二次传递,将所有复制引用设置为Null。(如果你这样做,你不必有一个copyCount,但一个布尔iscopy就足够了,因为你可以在第二步重置值。)

我用Object.assign解决了克隆对象数组的问题

const newArray = myArray.map(a => Object.assign({}, a));

如果使用扩展语法,甚至更短

const newArray = myArray.map(a => ({...a}));
person1 = {
    name: 'Naved',
    last: 'Khan',
    clothes: {
        jens: 5,
        shirts: 10
    }
};

person2 = {
    name: 'Naved',
    last: 'Khan'
};

// first way  shallow copy single lavel copy 
// const person3 = { ...person1 };

// secound way shallow copy single lavel copy
// const person3 = Object.assign({}, person1);

// third  way shallow copy single lavel copy but old 
// const person3 = {};
// for (let key in person1) {
//  person3[key] = person1[key];
// }

// deep copy with array and object best way
const person3 = JSON.parse(JSON.stringify(person1));

    person3.clothes.jens = 20;

console.log(person1);
console.log(person2);
console.log(person3);

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

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