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

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

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


当前回答

我个人认为Array.from是一个更具可读性的解决方案。顺便说一句,请注意它的浏览器支持。

//克隆设x=[1,2,3];设y=数组.来自(x);console.log({y});//深层克隆让clone=arr=>Array.from(arr,item=>Array.isArray(item)?克隆(项目):项目);x=[1,[],[[]]];y=克隆(x);console.log({y});

其他回答

快速示例:

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

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]]

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

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

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

阅读更多信息

不需要jQuery。。。工作示例

var arr2 = arr1.slice()

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

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

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

使用此项:

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

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

还应注意:

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

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

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

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

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

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