[英]Array.concat reflects the change in resulting array when input nested array is modified after concatination
根據 MDN, concat 的描述如下,
concat() 方法用於合並兩個或多個數組。 此方法不會更改現有數組,而是返回一個新數組。
考慮下面的代碼,
示例 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
輸出
[["a"], "b", "c", "d", "e", "f"]
[["a"], "b", "c", "d", "e", "f"]
示例 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?
輸出
[["a"], "b", "c", "d", "e", "f"]
[["a", "pushed"], "b", "c", "d", "e", "f"]
在示例 2 中,為什么即使連接發生在array1
的新元素推送之前, array3
的內容array3
發生變化。
注意:這兩個示例之間的唯一區別是
示例 1: array1.push('pushed')
示例 2: array1[0].push('pushed')
我了解按值傳遞和按引用傳遞(以及數組和對象共享引用),但讓我感到困惑的是為什么嵌套數組共享引用而原始數組被復制。
array1
中索引0
處的元素(非基元)通過引用復制到由array1.concat(array2)
返回的新數組中,並存儲在array3
。
.push()
在原地改變數組。 當您改變array1
,它不會影響array3
因為它們不共享相同的引用( concat
返回一個新數組)。
但是因為array1
中索引0
處的元素(非基元)與array3
中索引0
處的元素共享相同的引用(您可以通過查看array1[0] === array3[0]; // true
),改變array1
中的array1
就是改變array3
的相同數組。
TLDR: array1 !== array3
但array1[0] === array3[0]
我了解按值傳遞和按引用傳遞(以及數組和對象共享引用),但讓我感到困惑的是為什么嵌套數組共享引用而原始數組被復制。
這就是Array.concat
工作原理,它返回新數組中相同元素的副本。
您可以使用Spread syntax
做同樣的事情:
const array3 = [...array1, ...array2];
我們有來自array1
和array2
的相同元素的副本,但是在一個新的數組[]
,所以如果一個元素是一個數組或一個對象,它將通過引用復制
看這個例子:
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]);
使用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]);
除了上面發布的那些好的答案之外,這是一篇有趣且解釋清楚的關於深拷貝和淺拷貝的文章。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.