将JavaScript中的数组复制到另一个数组时:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

我意识到arr2指的是与arr1相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?


当前回答

只是在写:

arr2 = arr1.concat();

您正在使用第一个数组的副本生成新数组。请注意,这是将元素推入数组的一种功能方式。

如果您的代码基于ES6,您也可以使用扩展运算符:

arr2 = [...arr1];

其他回答

这是我在尝试了许多方法之后所做的:

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

这将创建一个与第一个副本无关的新深度副本(而不是浅层副本)。

此外,这显然不会克隆事件和函数,但您可以在一行中完成它,并且它可以用于任何类型的对象(数组、字符串、数字、对象…)

不需要jQuery。。。工作示例

var arr2 = arr1.slice()

这将从起始位置0到阵列末端复制阵列。

重要的是要注意,它将按照原始类型(字符串、数字等)的预期工作,并解释引用类型的预期行为。。。

如果您有一个引用类型数组,那么就说Object类型。将复制该数组,但这两个数组都将包含对同一对象的引用。因此,在这种情况下,即使实际复制了数组,也似乎通过引用复制了数组。

var arr2=arr1.slice(0);

这种方法只适用于简单数组。

如果您有类似复杂阵列的对象阵列,则必须使用其他解决方案,如:

const arr2 = JSON.parse(JSON.stringify(arr1)); 

例如,我们有一个对象数组,每个单元格的对象中都有另一个数组字段。。。在这种情况下,如果我们使用切片方法,那么数组字段将通过Ref进行复制,这意味着这些字段更新将影响原始数组中的相同元素和字段。

快速示例:

如果数组中的元素是基元类型(字符串、数字等)

var arr1=[‘a’,‘b’,‘c’];//arr1和arr2是独立的,基本元素存储在//记忆中的不同位置var arr2=arr1.slice();arr2.推('d');console.log(arr1);//[“a”、“b”、“c”]console.log(arr2);//[“a”、“b”、“c”、“d”]

如果数组中的元素是对象文本,则另一个数组({},[])

var arr1=[{x:'a',y:'b'},[1,2],[3,4]];//arr1和arr2是独立的,引用的/地址存储在不同的//记忆中的位置。但这些参考文献/地址指向了一些共同的地方//在存储器中。var arr2=arr1.slice();arr2.pop();//好-不影响arr1 bcos,只有arr2中的地址是//删除的不是该地址所指向的数据arr2[0].x=“z”;//不正常-影响在公共区域进行的arr1 bcos更改//由arr1和arr2中的地址指示arr2[1][0]=9;//不正常-与上述原因相同console.log(arr1);//[{x:'z',y:'b'},[9,2],[3,4]]console.log(arr2);//[{x:'z',y:'b'},[9,2]]

解决方案2:逐元素深度复制

var arr1=[{x:'a',y:'b'},[1,2],[3,4]];arr2=JSON.parse(JSON.stringify(arr1));arr2.pop();//OK-不影响arr1arr2[0].x=“z”;//好-不影响arr1arr2[1][0]=9;//OK-不影响arr1console.log(arr1);//[{x:“a”,y:“b”},[1,2],[3,4]]console.log(arr2);//[{x:'z',y:'b'},[9,2]]

使用此项:

让oldArray=[1,2,3,4,5];let newArray=oldArray.slice();console.log({newArray});

基本上,slice()操作克隆数组并返回对新数组的引用。

还应注意:

对于引用、字符串和数字(而不是实际对象),slice()将对象引用复制到新数组中。原始数组和新数组都引用同一对象。如果引用的对象发生更改,则这些更改对新阵列和原始阵列都可见。

字符串和数字等基元是不可变的,因此不可能更改字符串或数字。