先来看下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());
.