Javascript (深度)使用jQuery复制数组

Javascript (深度)使用jQuery复制数组,javascript,jquery,Javascript,Jquery,可能重复: 我需要复制一个(有序的,非关联的)对象数组。我正在使用jQuery。我最初试过 jquery.extend({}, myArray) 但是,很自然,这会返回一个对象,在这里我需要一个数组(顺便说一句,我非常喜欢jquery.extend) 那么,复制数组的最佳方法是什么 $.extend(true、[]、[[a'、[c']]、[b']) 这应该可以满足您的需要。我知道您正在寻找阵列的“深层”副本,但如果您只有一个单层阵列,则可以使用以下方法: 复制本机JS数组很容易。使用创建阵列

可能重复:

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

jquery.extend({}, myArray)
但是,很自然,这会返回一个对象,在这里我需要一个数组(顺便说一句,我非常喜欢jquery.extend)

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

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

这应该可以满足您的需要。

我知道您正在寻找阵列的“深层”副本,但如果您只有一个单层阵列,则可以使用以下方法:

复制本机JS数组很容易。使用创建阵列部分/全部副本的方法

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,但它确实很深


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

由于array.slice()不进行深度复制,因此它不适用于多维数组:

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

b.shift().shift();
// a is now [[], [2], [3]]
请注意,尽管我在上面使用了
shift().shift()
,但重点是
b[0][0]
包含指向
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]]

我计划在的下一个版本中发布此代码,但在此之前,如果您的目标是对阵列进行深度复制,则可以使用此代码:

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

您可以使用此代码。

如果您想使用纯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
var arr=[“苹果”、“球”、“猫”、“狗”];
var-narr=[];
对于(var i=0;i复杂类型如何?
当数组包含对象…或任何其他对象时

我的变体:

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

谢谢Noah。看起来我最大的问题是我把$.extend和object作为它的第一个参数,而不是数组。你能解释一下b.shift()的用途吗这里?b只是被操纵以显示a和b不具有相同的值。a和b不应该表示为[[3]]?Shift会完全删除数组中的第一个值,无论该值是否为任何类型。它不会对基元类型执行递归搜索,然后删除该值。保存该方法上下文的数组的长度始终减少1,并在适当的位置进行编辑。谢谢!您的行:var b=$.extend(true,[],a);救了我的命!我用了$.extend(true,{},a)大括号而不是方括号!非常感谢它的帮助,通常当我们通过直接赋值方式复制数组时,当一个数组被更改时,另一个被复制的数组也会被更改,所以这个方法会进行真正的复制。谢谢,我们正在寻找一个全面的克隆(有时有一个对象,有时是一个对象数组)。请注意,这不是一个深度副本。类似:var a=[1,2,3];var b=([])。concat(a);b是一个copyArray.slice不提供深度副本,这正是这里要问的问题。作者在括号中加了深括号,所以任何关于复制的答案都是受欢迎的。实际问题的文本甚至根本不包含deep这个词。有趣。@Chris West你能说一下你的答案所针对的问题吗jQuery扩展没有?非常感谢。原语不是通过引用传递的。但是对象(包括数组)是通过引用传递的。这对多维数组不起作用,您必须使用@Noah sussma在回答中提到的“true”作为第一个参数。如果您不想返回对象,则指定
[]
而不是
{}
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;
}