(深)使用jQuery复制数组

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

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

jquery.extend({}, myArray) 

但是,自然,这给了我一个对象,在那里我需要一个数组(真的爱jquery.extend,顺便说一句)。

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

由于Array.slice()不执行深度复制,因此不适用于multidimensional array:

 var a =[[1], [2], [3]]; var b = a.slice(); b.shift().shift(); // a is now [[], [2], [3]] 

请注意,尽pipe我已经使用了上面的shift().shift() ,但是b[0][0]包含一个指向b[0][0]的指针,而不是一个值。

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

当一个真实的值作为初始parameter passing时,jQuery的extend方法执行深层复制:

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

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

这应该为你做。

我意识到你正在寻找一个“深”的数组副本,但如果你只有一个单一的水平数组,你可以使用这个:

复制本地JS Array很容易。 使用Array.slice()方法创build数组的一部分/全部副本。

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

现在foo和bar是“a”,“b”,“c”,“d”,“e”

当然,酒吧是一个副本,而不是一个参考…所以,如果你做了下一个…

 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,然后将其反序列化。

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

我遇到了这个“深层对象复制”的function,我发现这个function很有价值。 它不使用jQuery,但肯定是深刻的。

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

我打算在下一个版本的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(jb); levels[level].i = i + 1; levels[++level] = {a:item, b:jb, 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); } }; 

以下是如何调用此函数来执行recursion数组的深层副本的示例:

 // 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里玩这个代码。

复杂types如何? 当数组包含对象…或任何其他

我的变体:

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