Array.prototype.fill 填充值被複用的問題

劉哇勇發表於2021-04-18

考察如下示例程式碼:

// 建立二維陣列
const arr = Array(2).fill([]);

// 操作第一個元素
arr[0].push(1);

// 結果是操作了所有陣列
console.log(arr); // [ [ 1 ], [ 1 ] ]

和 new 不 new 關係,以下程式碼問題同樣存在

- const arr= Array(12).fill([])
+ const arr= new Array(12).fill([])

arr[0].push(1)

console.log(arr); // [ [ 1 ], [ 1 ] ]

問題出在這個 fill,根據 MDN 的描述

The fill() method changes all elements in an array to a static value
MDN Array.prototype.fill()

arr.fill(value[, start[, end]]) 這裡使用 value 替換陣列中的元數,當 value 為物件字面量時,這個物件是被共用的,並沒有為每個元素重新建立副本。所以當操作其中一個元素時,所有元素都被影響了。本例中,使用 [] 這個陣列字面量填充陣列,操作其中任意元數導致所有元素變更。

修正方式則是通過 Array.prototype.map 將每個元素重新賦值,解除這裡的複用。

const arr = Array(2)
.fill(1)
.map((item) => []);

arr[0].push(1);

// 結果是操作了所有陣列
console.log(arr); // [ [ 1 ], [] ]

之所以在 Array(number) 建立好指定長度的空陣列後還需要 fill 填充一下,是因為不填充的話,空陣列不能被實際操作,即不能 pushmap 等,列印出來如下:

[ <2 empty items> ]

相關資源

The text was updated successfully, but these errors were encountered:

相關文章