array.prototype.fill()原地修改数组,不创建新数组;new array(n).fill(value)可快速初始化基本类型数组,但引用类型会共享内存,需用array.from生成独立副本。

fill 会修改原数组,不是创建新数组
Array.prototype.fill 不返回新数组,而是直接在调用者上做原地填充。如果你写 const arr = [].fill(0, 0, 5),结果是空数组([]),因为 [] 长度为 0,fill 对长度为 0 的数组无效。
正确做法是先构造出目标长度的数组,再填值:
- 用
new Array(n)创建稀疏数组(注意:它不含任何元素,只是 length 被设为 n) - 再链式调用
.fill(value),此时才真正写入默认值
例如:new Array(5).fill(0) → [0, 0, 0, 0, 0]
fill 的 start 和 end 参数容易误用
第三个参数 end 是**不包含**的右边界,和 slice 一致。但很多人以为它是“填充个数”,导致少填或多填。
常见错误写法:new Array(10).fill('x', 0, 3) → 只填前 3 个位置,结果是 ['x','x','x', empty ×7],不是长度为 3 的数组。
关键点:
-
start和end是索引,不是数量 - 负数索引从末尾算起:
new Array(5).fill('a', -2)填最后两个位置 - 如果
start > end或超出范围,不报错但无效果
引用类型默认值会共享同一份内存
当用对象、数组等引用类型做默认值时,fill 会把**同一个引用**复制到每个位置,后续修改会相互影响。
例如:new Array(3).fill({ a: 1 }) → 所有元素指向同一个对象。改 arr[0].a = 99,arr[1].a 也变成 99。
要避免共享,必须用 map 或循环生成独立副本:
- 对象:
Array.from({ length: 3 }, () => ({ a: 1 })) - 数组:
Array.from({ length: 3 }, () => []) - 不能用
new Array(3).fill([])—— 它只创建一个空数组并复用三次
性能对比:fill vs Array.from vs 循环
对基本类型(数字、字符串、null、undefined),fill 是最快的,因为它底层高度优化,且是原生方法。
但要注意兼容性:
-
fill在 IE 中完全不支持,Node.js 4+ 开始支持 -
Array.from同样不支持 IE,但能安全处理引用类型初始化 - 如果需兼容老环境或动态计算值,还是得用
for循环
简单场景优先用 new Array(n).fill(value);涉及对象/需兼容性/需映射逻辑时,换 Array.from。










