数组“孔洞”指未定义索引的位置,不占内存、不参与遍历;Object.keys()不返回孔洞索引,但显式赋undefined会保留;forEach等跳过孔洞,处理显式undefined;控制台显示为empty×N;length由最大索引+1决定。

识别数组的“孔洞”,关键在于区分 索引是否存在,而不是值是否为 undefined。孔洞是 JS 数组中“未定义索引”的位置——它不占用内存、不参与遍历、也不被大多数数组方法感知。
用 Object.keys() 和 hasOwnProperty() 检查真实索引
孔洞位置在 Object.keys() 中完全不会出现,而显式赋值 undefined 的位置会保留索引:
-
const a = []; a[2] = 'x';→Object.keys(a)返回['2'],a.hasOwnProperty(0)是false -
const b = [undefined, undefined, 'x'];→Object.keys(b)返回['0', '1', '2'],b.hasOwnProperty(0)是true
观察遍历行为差异
原生迭代方法(forEach、map、filter、every)对孔洞完全跳过,但会处理显式 undefined 元素:
-
[1, , 3].forEach(x => console.log(x))只输出1和3 -
[1, undefined, 3].forEach(x => console.log(x))输出1、undefined、3
查看控制台输出的视觉提示
现代浏览器控制台会明确标注孔洞:显示为 empty 或 empty × N,而非 undefined:
-
new Array(3)在 Chrome 控制台显示为[empty × 3] -
[undefined, undefined, undefined]显示为[undefined, undefined, undefined]
检查 length 与实际元素数量的关系
稀疏数组的 length 常远大于有效元素个数,且最大索引 + 1 决定长度,中间无映射即为空洞:
-
const s = []; s[99] = 'last';→s.length === 100,但只有 1 个真实元素 - 密集数组如
Array.from({length: 100})长度为 100,且每个索引都存在(即使值为undefined)

















