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

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

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


当前回答

在我的特殊情况下,我需要确保阵列保持完整,所以这对我来说很有用:

// Empty array
arr1.length = 0;
// Add items from source array to target array
for (var i = 0; i < arr2.length; i++) {
    arr1.push(arr2[i]);
}

其他回答

structuredClone是一种新的深度克隆方法。

structuredClone(value)
structuredClone(value, { transfer })

transfer是一个值可转移对象数组,它将被移动而不是克隆到返回的对象中。

你可能会发现它的算法很有趣。

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

// 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安慰

使用此项:

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

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

还应注意:

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

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

如果您的数组包含原始数据类型的元素,如int、char或string等,那么您可以使用其中一种方法来返回原始数组的副本,如.slice()或.map()或spread运算符(得益于ES6)。

new_array = old_array.slice()

or

new_array = old_array.map((elem) => elem)

or

const new_array = new Array(...old_array);

但是如果您的数组包含复杂元素,例如对象(或数组)或更多嵌套对象,那么,您必须确保从顶层到最后一层复制所有元素,否则将使用内部对象的引用,这意味着更改new_array中object_elements的值仍将影响旧_array。您可以将这种复制方法称为“深度复制”旧数组的。

对于深度复制,您可以根据数据类型在每个级别对原始数据类型使用上述方法,也可以使用这种成本高昂的方法(如下所述)进行深度复制,而无需做大量工作。

var new_array = JSON.parse(JSON.stringify(old_array));

根据您的需求,还有很多其他方法可以使用。我只提到了其中的一些,它们可以让我们大致了解当我们试图按值将一个数组复制到另一个数组时会发生什么。

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

arr2 = [...arr1];

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