简体   繁体   English

Array.concat 反映输入嵌套数组拼接后修改结果数组的变化

[英]Array.concat reflects the change in resulting array when input nested array is modified after concatination

According to MDN, the description for concat is as below,根据 MDN, concat 的描述如下,

The concat() method is used to merge two or more arrays. concat() 方法用于合并两个或多个数组。 This method does not change the existing arrays, but instead returns a new array.此方法不会更改现有数组,而是返回一个新数组。

Consider the below code,考虑下面的代码,

Example 1示例 1

 const array1 = [['a'], 'b', 'c']; const array2 = ['d', 'e', 'f']; const array3 = array1.concat(array2); // concatinate array1 and array2 and returns new array3. console.log(array3); array1.push('pushed'); // pushed as the last element to the array1 console.log(array3); // no change in array 3, looks correct

output输出

[["a"], "b", "c", "d", "e", "f"]  
[["a"], "b", "c", "d", "e", "f"]

Example 2:示例 2:

 const array1 = [['a'], 'b', 'c']; const array2 = ['d', 'e', 'f']; const array3 = array1.concat(array2); // concatinate array1 and array2 and returns new array3. console.log(array3); array1[0].push('pushed'); // pushed as the last element to the nested array at position 0 console.log(array3); // array 3 also changed, why?

output输出

[["a"], "b", "c", "d", "e", "f"]  
[["a", "pushed"], "b", "c", "d", "e", "f"]      

In the example 2, why did the content of array3 got changed even though the concatenation happened before the push of new element in array1 .在示例 2 中,为什么即使连接发生在array1的新元素推送之前, array3的内容array3发生变化。

NOTE : the only difference between the 2 examples is注意:这两个示例之间的唯一区别是
Example1: array1.push('pushed')示例 1: array1.push('pushed')
Example2: array1[0].push('pushed')示例 2: array1[0].push('pushed')

I understand about pass by value and pass by reference (and arrays and objects share reference), but the thing which confused me is why is the nested array sharing reference and the original array was copied.我了解按值传递和按引用传递(以及数组和对象共享引用),但让我感到困惑的是为什么嵌套数组共享引用而原始数组被复制。

The element at index 0 in array1 (a non primitive ) was copied by reference in the new array returned by array1.concat(array2) and stored in array3 . array1中索引0处的元素(非基元)通过引用复制到由array1.concat(array2)返回的新数组中,并存储在array3

.push() mutates the array in place. .push()在原地改变数组。 When you mutate array1 , it does not affect array3 because they do not share the same reference ( concat returned a new array).当您改变array1 ,它不会影响array3因为它们不共享相同的引用( concat返回一个新数组)。

But because the element at index 0 in array1 (a non primitive ) is sharing the same reference as the element at index 0 in array3 (which you can check by seeing that array1[0] === array3[0]; // true ), mutating that array in array1 is mutating the same array in array3 .但是因为array1中索引0处的元素(非基元)与array3中索引0处的元素共享相同的引用(您可以通过查看array1[0] === array3[0]; // true ),改变array1中的array1就是改变array3的相同数组。

TLDR: array1 !== array3 but array1[0] === array3[0] TLDR: array1 !== array3array1[0] === array3[0]

I understand about pass by value and pass by reference (and array and objects share reference), but the thing which confused me is why is the nested array sharing reference and the original array was copied.我了解按值传递和按引用传递(以及数组和对象共享引用),但让我感到困惑的是为什么嵌套数组共享引用而原始数组被复制。

That's how Array.concat works, it returns copies of the same elements in a new array .这就是Array.concat工作原理,它返回新数组中相同元素的副本

You can do the same thing using Spread syntax :您可以使用Spread syntax做同样的事情:

const array3 = [...array1, ...array2];

We have copies of the same elements from array1 and array2 but in a new array [] , so if an element is an array or an object it'll be copied by reference我们有来自array1array2的相同元素的副本,但是在一个新的数组[] ,所以如果一个元素是一个数组或一个对象,它将通过引用复制

Look at this example:看这个例子:

 const array1 = [['a'], 'b', 'c']; const array3 = array1.concat(); console.log('array3:', array3); console.log('array3 === array1 ? :', array3 === array1); console.log('array3[0] === array1[0] ? :', array3[0] === array1[0]);

The same example using Spread syntax :使用Spread syntax的相同示例:

 const array1 = [['a'], 'b', 'c']; const array3 = [...array1]; console.log('array3:', array3); console.log('array3 === array1 ? :', array3 === array1); console.log('array3[0] === array1[0] ? :', array3[0] === array1[0]);

Apart from those good answers posted above, Here is an interesting and a well explained article about deep and shallow copy.除了上面发布的那些好的答案之外,这是一篇有趣且解释清楚的关于深拷贝和浅拷贝的文章。

how-to-differentiate-between-deep-and-shallow-copies by Lukas Gisder-Dubé Lukas Gisder-Dubé 的《如何区分深浅副本》

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM