簡體   English   中英

Array.concat 反映輸入嵌套數組拼接后修改結果數組的變化

[英]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 !== array3array1[0] === array3[0]

我了解按值傳遞和按引用傳遞(以及數組和對象共享引用),但讓我感到困惑的是為什么嵌套數組共享引用而原始數組被復制。

這就是Array.concat工作原理,它返回新數組中相同元素的副本

您可以使用Spread syntax做同樣的事情:

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

我們有來自array1array2的相同元素的副本,但是在一個新的數組[] ,所以如果一個元素是一個數組或一個對象,它將通過引用復制

看這個例子:

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

除了上面發布的那些好的答案之外,這是一篇有趣且解釋清楚的關於深拷貝和淺拷貝的文章。

Lukas Gisder-Dubé 的《如何區分深淺副本》

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM