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

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

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


当前回答

以下是如何对可变深度的基元数组执行此操作:

// If a is array: 
//    then call cpArr(a) for each e;
//    else return a

const cpArr = a => Array.isArray(a) && a.map(e => cpArr(e)) || a;

let src = [[1,2,3], [4, ["five", "six", 7], true], 8, 9, false];
let dst = cpArr(src);

https://jsbin.com/xemazog/edit?js安慰

其他回答

重要的

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

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

let clonedArray=[…array]

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

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

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


对于lodash用户:

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

and

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

不需要jQuery。。。工作示例

var arr2 = arr1.slice()

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

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

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

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

那么我们如何复制这个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';

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

阅读更多信息

您可以将ES6与spread Opartor一起使用,它更简单。

arr2 = [...arr1];

有一些限制。。check docs Spread语法@mozilla

切片的另一种选择是凹面,可以用两种方式。第一个可能更容易理解,因为预期行为非常清楚:

var array2 = [].concat(array1);

第二种方法是:

var array2 = array1.concat();

科恩(在评论中)指出,后一种方法具有更好的性能。

其工作方式是concat方法创建一个新数组,该数组由调用它的对象中的元素组成,后跟作为参数传递给它的任何数组的元素。因此,当没有传递参数时,它只是复制数组。

Lee Penkman也在评论中指出,如果array1有可能未定义,可以返回一个空数组,如下所示:

var array2 = [].concat(array1 || []);

或者,对于第二种方法:

var array2 = (array1 || []).concat();

请注意,您也可以使用slice:var array2=(array1||[]).slice();执行此操作;。