先來看下fill方法的介紹
Array.prototype.fill()
fill() 方法用一個固定值填充一個數組中從起始索引到終止索引內的全部元素(不包括終止索引)。
再來看下該方法的入參細節
/** * @param {*} value - 用來填充數組元素的值 * @param {number} [start] - 起始索引(默認爲0) * @param {number} [end] - 終止索引(默認爲數組的長度) */ fill(value, start, end);
那麼,看個🌰例子:
const arr = new Array(5).fill([]); // 被填充後的arr: // [ [], [], [], [], [] ] arr[1].push(0);
這裏有個問題,再執行 arr[1].push(0) 語句後,arr變成了什麼樣子?
是下面這樣,對吧:
// arr: // [ [], [0], [], [], [] ]
No !
實際上,arr變成了下面這樣:
// real arr: // [ [0], [0], [0], [0], [0] ]
所以,如果 fill() 的第一個參數爲1個引用類型,那麼需要注意,目標數組中特定範圍內的元素都將指向同一個引用。
參見 Polyfill 中的代碼實現的關鍵部分:
// ... other codes while (k < final) { O[k] = value; k++; } // ... remaining codes
如果想避免上述例子所出現的情況,可以參考下面的方式進行處理:
const arr = new Array(3).fill(void 0).map(() => []); // OR const arr = new Array(3).fill(void 0).map(() => new Array());
.