Array(n) 创建的是含 n 个空位的稀疏数组,非 undefined 填充的密集数组;空位无键名,遍历时被 forEach/map 等跳过,而 undefined 是真实可枚举值,会被正常处理。

Array(n) 创建的是含 n 个空位(empty slots) 的稀疏数组,不是由 undefined 填充的密集数组。这个区别在迭代时表现得非常关键——空位会被多数高阶方法跳过,而 undefined 是真实存在的值,会被正常处理。
空位 ≠ undefined:本质不同
空位表示“该索引位置根本不存在”,连键名都没有;undefined 是一个合法的、可枚举的值,占据实际键位。
-
0 in Array(3)→ false(0 号位置无键) -
0 in [undefined, undefined, undefined]→ true(0 号位置有键,值为undefined)
迭代行为差异明显
ES5 中大多数数组方法对空位“视而不见”,但对 undefined 会照常执行回调:
-
forEach、map、filter、every、some:跳过空位,不调用回调;遇到undefined则正常调用 -
for...of和普通for循环:把空位当作undefined处理(即读取返回undefined,但不会跳过索引) -
join()和toString():将空位等同于undefined,最终转为空字符串
常见陷阱示例
这两段代码结果完全不同:
-
Array(3).map(() => 'x')→[empty × 3](map不遍历空位,返回原样) -
[undefined, undefined, undefined].map(() => 'x')→['x', 'x', 'x'](三个undefined都被遍历)
控制台显示可能误导你——两者都打印成 [undefined, undefined, undefined],但内部结构和行为截然不同。
如何避免混淆
- 创建固定长度数组时,优先用
Array.from({ length: n }, () => undefined)或new Array(n).fill()(fill()会填充所有位置,包括空位) - 需要稀疏数组时明确意图,否则统一使用字面量
[]或Array.of() - 调试时别只看
console.log输出,用in运算符或Object.keys(arr)检查键是否存在

















