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

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

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


当前回答

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

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

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

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

其他回答

基本体值始终按其值传递(复制)。但是,复合值是通过引用传递的。

那么我们如何复制这个arr?

let arr = [1,2,3,4,5];

在ES6中复制阵列

let arrCopy = [...arr]; 

在ES5中复制n阵列

let arrCopy = arr.slice(); 
let arrCopy = [].concat(arr);

为什么“let arrCopy=arr”不按值传递?

将一个变量传递给另一个复合值(例如“对象/数组”)会有不同的行为。在共和值上使用sign运算符,我们将引用传递给对象。这就是为什么在删除/添加arr元素时,两个数组的值都会发生变化。

例外情况:

arrCopy[1] = 'adding new value this way will unreference';

为变量指定新值时,将更改引用本身,而不会影响原始对象/数组。

阅读更多信息

let a = [1,2,3];

现在,您可以执行以下任一操作来创建阵列的副本。

let b = Array.from(a); 

OR

let b = [...a];

OR

let b = new Array(...a); 

OR

let b = a.slice(); 

OR

let b = a.map(e => e);

现在,如果我改变一个,

a.push(5); 

那么,a是[1,2,3,5],但b仍然是[1,3,3],因为它有不同的引用。

但我认为,在上述所有方法中,Array.from都更好,并且主要用于复制数组。

不需要jQuery。。。工作示例

var arr2 = arr1.slice()

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

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

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

重要的

这里的大多数答案适用于特定情况。

如果您不关心深度/嵌套对象和道具,请使用(ES6):

let clonedArray=[…array]

但如果要进行深度克隆,请改用以下方法:

let cloneArray=JSON.parse(JSON.stringify(数组))*

*函数在使用stringify时不会被保存(序列化),如果没有它们,您将得到结果。


对于lodash用户:

let clonedArray=_.clone(数组)文档

and

let cloneArray=_.cloneDeep(数组)文档

var arr2=arr1.slice(0);

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

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

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

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