jQuery中是否有一种方法可以克隆一个数组?

64

这是我的代码:

var a=[1,2,3]
b=$.clone(a)
alert(b)

jQuery没有'clone'方法吗?我该如何使用jQuery克隆一个数组?


有关多维数组克隆,请参见- https://dev59.com/hEzSa4cB1Zd3GeqPjRSK - vsync
是的,jQuery有一个克隆方法,并且可以使用设置为true的深度参数进行扩展。请参见http://api.jquery.com/clone/和http://api.jquery.com/jquery.extend/。对于少量数据的快速和简单选项是使用JSON.parse(JSON.stringify(original))。对于大量数据,也许您不应该进行克隆?! - podperson
使用扩展运算符 - zloctb
8个回答

166

1
这与 slice(0) 是同义词吗? - Peter Ajtai
7
谢谢你,meder。唯一需要注意的是,数组是对象,因此您可以附加属性和方法,比如var a=[1,2,3]; a.foo = function() { alert(this); };使用slice()复制时,不会复制任何附加的属性和方法,所以您不能执行b.foo()...我提及这一点是因为jQuery的.clone()包括深层复制选项。例如:http://jsfiddle.net/B2LQL/......但在这个问题的背景下,这几乎是一个小角落的情况。 - Peter Ajtai
12
注意:这里进行的是浅拷贝而非深拷贝,因此数组中的任何对象都不会被复制,只会被引用。 - Ariel
@Ariel,那么你如何进行深拷贝? - Arman Bimatov
@ArmanBimatov 抱歉,我不记得我做了什么。我想我只是使用了一个对象。请参见:http://forum.jquery.com/topic/jquery-extend-modifies-but-not-replaces-array-properties-on-deep-copy - Ariel
显示剩余2条评论

11

1
这也进行了浅层复制,因此等同于被接受的答案。 - rych
1
@rych 这并不等同,因为它也适用于没有 .slice 方法的类似数组的对象(例如 NamedNodeMap)。 - janek37

7

更改

b=$.clone(a) 改为 b=$(this).clone(a) ,但有时候不起作用。

但是已经有人报告过这个问题了。

http://www.fusioncube.net/index.php/jquery-clone-bug-in-internet-explorer

解决方案 您可以使用 JavaScript 中内置的简单克隆函数。

var a=[1,2,3];
b=clone(a);
alert(b);

function clone(obj){
    if(obj == null || typeof(obj) != 'object')
        return obj;
    var temp = obj.constructor();
    for(var key in obj)
        temp[key] = clone(obj[key]);
    return temp;
}

一个很好的选择是

 // Shallow copy
  var b = jQuery.extend({}, a);

  // Deep copy
  var b = jQuery.extend(true, {}, a);

-约翰·雷西格(John Resig)

查看类似的帖子


2
日本- Extend 适用于对象。您的第一个函数也适用于对象。 - neoswf
1
扩展运算符对于数组也非常好用,只需要将空对象{}改为空数组[]即可。 - Chris Leonard
当我使用extend()并传入{}时,它没有正常工作。如果我传入[],它可能会起作用。 - John Gilmer

7
这是我的做法:

我是这样做的:

var newArray = JSON.parse(JSON.stringify(orgArray));

这将创建一个新的深拷贝,与第一个不相关(不是浅拷贝)。

此外,显然这不会克隆事件和函数,但好处是你可以在一行代码中完成,并且可用于任何类型的对象(数组、字符串、数字、对象等)。


1
这显然不是一个适合大型、复杂结构的正确选择,但它是一个相当简洁的一行代码,并且实际上是我最终采用的方法。 - podperson

2

ES6 请使用展开运算符

let arrayCopy = [...myArray];

1

尝试

if (!Array.prototype.clone) {
    Array.prototype.clone = function () {
        var arr1 = new Array();
        for (var property in this) {
            arr1[property] = typeof (this[property]) == 'object' ? this[property].clone() : this[property]
        }
        return arr1;
    }​
}

用作

var a = [1, 2, 3]
b = a;
a.push(4)
alert(b); // alerts [1,2,3,4]
//---------------///
var a = [1, 2, 3]
b = a.clone();
a.push(4)
alert(b); // alerts [1,2,3]​

这是为了防止您除了数组中的值之外,还将其他属性附加到数组上(而不仅仅使用slice(0))? - Peter Ajtai
@Peter-“slice(0)”不错。我只是展示另一种解决方法。;) - Reigel Gallarde

1

另一个选项是使用Array.concat:

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

基本上和使用切片一样的问题。 - podperson

0

var a=[1,2,3]
b=JSON.parse(JSON.stringify(a));
document.getElementById("demo").innerHTML = b;
<p id="demo"></p>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接