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

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

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);
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);

我想我们可以做到->

let a = [{name: "mike"}, {name: "ron"}];
let copy_a = [...a];

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

我使用新的ECMAScript 6对象。分配方法:

let oldObject = [1, 3, 5, "test"];
let newObject = Object.assign({}, oldObject);

该方法的第一个参数是要更新的数组。我们传递一个空对象,因为我们想要有一个新对象。

我们也可以使用这个语法,它是相同的,但更短:

let newObject = [...oldObject];