Array(n).fill(val)适用于原始类型默认值,但对象数组需用Array.from避免引用共享;空位数组行为异常,fill可填平但有边界。

fill 方法初始化数组的正确姿势
fill 本身不创建数组,只填充已有数组。直接 Array(5).fill(0) 看似可行,但结果是 [0, 0, 0, 0, 0] —— 这依赖于 Array 构造函数生成的“空位数组”在调用 fill 时被统一处理。可它本质脆弱:空位(empty slots)在某些操作中行为异常,比如 map 会跳过它们,而 fill 恰好能“填平”,所以这招能用,但得知道边界。
- ✅ 正确写法:
Array(5).fill(0)或new Array(5).fill('default') - ❌ 错误写法:
Array(5).fill().map(() => 0)——fill()不传参时填undefined,但map对空位不执行回调,结果仍是空数组 - ⚠️ 注意:
Array(5)创建的是含 5 个空位的数组,不是 5 个undefined;但fill会把所有位置都设为指定值,包括原本的空位
fill 初始化对象数组要小心引用共享
用 fill 初始化对象数组时,所有元素指向同一引用。例如 Array(3).fill({id: 1}) 得到的三个对象修改任一,其余全变 —— 因为 fill 复制的是引用,不是深拷贝。
- ✅ 需独立对象:改用
Array.from({length: 3}, () => ({id: 1})) - ✅ 或映射索引:
Array(3).fill(null).map((_, i) => ({id: i + 1})) - ⚠️
fill({})是常见坑,尤其在 React state 初始化或表单字段批量生成时容易引发意外突变
替代方案:Array.from 更可控也更语义清晰
Array.from 显式声明长度并支持映射逻辑,比 fill 组合更直观,且天然规避引用共享问题(只要回调里新建对象)。
- ✅ 基础默认值:
Array.from({length: 4}, () => 'a') - ✅ 带索引的值:
Array.from({length: 3}, (_, i) => i * 2)→[0, 2, 4] - ✅ 兼容性:IE 不支持
Array.from,如需兼容,fill+map组合(确保先fill再map)更稳妥,但必须确认fill已执行
性能和场景选择:小数组无差别,大数组注意 fill 的底层优化
V8 等引擎对 fill 有底层内存填充优化,纯数值或简单值初始化时,Array(n).fill(value) 通常比 Array.from 略快;但一旦涉及函数调用(如对象构造),开销就转嫁到回调上,此时差异可忽略。
- ✅ 数值/字符串默认值、长度确定:优先
Array(n).fill(val) - ✅ 需每项不同、或含计算逻辑:用
Array.from({length: n}, fn) - ⚠️ 不要为了“看起来短”硬套
fill,尤其是初始化后立刻要map或forEach的场景——直接用Array.from更少出错
实际项目里,最常被忽略的是空位数组的隐式行为和对象引用陷阱。写 fill 前先问一句:这个默认值是原始类型,还是我真需要每个元素都独立?










