(深度)使用jQuery复制数组

< p > 可能的重复: < br > 复制JavaScript对象最有效的方法是什么? < / p >

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

jquery.extend({}, myArray)

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

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

123870 次浏览

$.extend(true, [], [['a', ['c']], 'b'])

这应该对你有帮助。

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

复制一个原生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

我遇到过这个“深度对象复制”函数,我发现它可以方便地按值复制对象。它没有使用jQuery,但它确实很有深度。

http://www.overset.com/2007/07/11/javascript-recursive-object-copy-deep-object-copy-pass-by-value/

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

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

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


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

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

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

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

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


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

我计划在jPaq的下一个版本中发布这段代码,但在那之前,如果你的目标是做数组的深度拷贝,你可以使用它:

Array.prototype.clone = function(doDeepCopy) {
if(doDeepCopy) {
var encountered = [{
a : this,
b : []
}];


var item,
levels = [{a:this, b:encountered[0].b, i:0}],
level = 0,
i = 0,
len = this.length;


while(i < len) {
item = levels[level].a[i];
if(Object.prototype.toString.call(item) === "[object Array]") {
for(var j = encountered.length - 1; j >= 0; j--) {
if(encountered[j].a === item) {
levels[level].b.push(encountered[j].b);
break;
}
}
if(j < 0) {
encountered.push(j = {
a : item,
b : []
});
levels[level].b.push(j.b);
levels[level].i = i + 1;
levels[++level] = {a:item, b:j.b, i:0};
i = -1;
len = item.length;
}
}
else {
levels[level].b.push(item);
}


if(++i == len && level > 0) {
levels.pop();
i = levels[--level].i;
len = levels[level].a.length;
}
}


return encountered[0].b;
}
else {
return this.slice(0);
}
};

下面是一个如何调用此函数对递归数组进行深度复制的示例:

// Create a recursive array to prove that the cloning function can handle it.
var arrOriginal = [1,2,3];
arrOriginal.push(arrOriginal);


// Make a shallow copy of the recursive array.
var arrShallowCopy = arrOriginal.clone();


// Prove that the shallow copy isn't the same as a deep copy by showing that
// arrShallowCopy contains arrOriginal.
alert("It is " + (arrShallowCopy[3] === arrOriginal)
+ " that arrShallowCopy contains arrOriginal.");


// Make a deep copy of the recursive array.
var arrDeepCopy = arrOriginal.clone(true);


// Prove that the deep copy really works by showing that the original array is
// not the fourth item in arrDeepCopy but that this new array is.
alert("It is "
+ (arrDeepCopy[3] !== arrOriginal && arrDeepCopy === arrDeepCopy[3])
+ " that arrDeepCopy contains itself and not arrOriginal.");

你可以使用这个代码这里是JS Bin

如果你想使用纯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

复杂类型怎么样? 当数组包含对象时…或任何其他

我的版本:

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:每个方法和包含的都是原型也。