可能的重复: 复制JavaScript对象最有效的方法是什么?

我需要复制一个(有序的,不是关联的)对象数组。我用的是jQuery。我最初尝试过

jquery.extend({}, myArray)

但是,自然地,这给了我一个对象,我需要一个数组(真的爱jquery。顺便说一下,延伸)。

复制数组的最佳方法是什么?


当前回答

因为Array.slice()不做深度复制,它不适合多维数组:

var a =[[1], [2], [3]];
var b = a.slice();

b.shift().shift();
// a is now [[], [2], [3]]

注意,虽然我上面使用了shift().shift(),但重点是b[0][0]包含一个指向[0][0]的指针,而不是一个值。

同样,delete(b[0][0])也会导致[0][0]被删除,b[0][0]=99也会将[0][0]的值更改为99。

jQuery的extend方法在传入true值作为初始参数时执行深度复制:

var a =[[1], [2], [3]];
var b = $.extend(true, [], a);

b.shift().shift();
// a is still [[1], [2], [3]]

其他回答

因为Array.slice()不做深度复制,它不适合多维数组:

var a =[[1], [2], [3]];
var b = a.slice();

b.shift().shift();
// a is now [[], [2], [3]]

注意,虽然我上面使用了shift().shift(),但重点是b[0][0]包含一个指向[0][0]的指针,而不是一个值。

同样,delete(b[0][0])也会导致[0][0]被删除,b[0][0]=99也会将[0][0]的值更改为99。

jQuery的extend方法在传入true值作为初始参数时执行深度复制:

var a =[[1], [2], [3]];
var b = $.extend(true, [], a);

b.shift().shift();
// a is still [[1], [2], [3]]

如果你想使用纯JavaScript,那么试试这个:

 var arr=["apple","ball","cat","dog"];
 var narr=[];

 for(var i=0;i<arr.length;i++){
     narr.push(arr[i]);
 }
 alert(narr); //output: apple,ball,vat,dog
 narr.push("elephant");
 alert(arr); // output: apple,ball,vat,dog
 alert(narr); // apple,ball,vat,dog,elephant

我知道你正在寻找一个数组的“深度”副本,但如果你只有一个单层数组,你可以使用这个:

复制一个原生JS数组很容易。使用array. slice()方法创建数组的部分或全部副本。

var foo = ['a','b','c','d','e'];
var bar = foo.slice();

foo和bar是a b c d e的5个数组

当然,酒吧是一个拷贝,而不是一个参考…所以如果你接下来做这个…

bar.push('f');
alert('foo:' + foo.join(', '));
alert('bar:' + bar.join(', '));

你现在会得到:

foo:a, b, c, d, e
bar:a, b, c, d, e, f

JavaScript中的所有内容都是通过引用传递的,所以如果您想要数组中对象的真正深度副本,我能想到的最好方法是将整个数组序列化为JSON,然后反序列化回来。

那么复杂类型呢? 当数组包含对象时…或者其他

我的版本:

Object.prototype.copy = function(){
    var v_newObj = {};
    for(v_i in this)
        v_newObj[v_i] = (typeof this[v_i]).contains(/^(array|object)$/) ? this[v_i].copy() : this[v_i];
    return v_newObj;
}

Array.prototype.copy = function(){
    var v_newArr = [];
    this.each(function(v_i){
        v_newArr.push((typeof v_i).contains(/^(array|object)$/) ? v_i.copy() : v_i);
    });
    return v_newArr;
}

这不是最终版本,只是一个想法。

PS:每个方法和包含的都是原型也。