遍历cells二维网格时出现TypeError: Cannot read property of undefined错误
核心问题根源
- 空值判断的顺序存在硬伤,完全没有起到兜底作用。
- 报错
TypeError: Cannot read property '-1' of undefined的触发过程根本走不到你写的typeof判断逻辑:当邻格遍历算出的yy值为-1时,cells[yy]本身就是undefined,此时直接执行cells[yy][xx],相当于在undefined上读取索引属性,JS引擎会直接抛出类型错误,后续代码完全不会执行。
当y=0、邻格遍历的yy值为-1时,实际执行流程为:
- 引擎先计算
cells[-1],得到的结果为undefined- 紧接着尝试读取
undefined[-1],直接触发报错中断,根本不会运行到typeof(cells[yy][xx]) !== 'undefined'的判断语句
修复方案
- 必须按照从外到内的顺序逐层校验索引合法性,禁止跳步直接访问嵌套数组的属性:
- 先校验邻格的行索引是否在网格有效行范围内:确认
yy >= 0且yy < cells.length,不满足则直接跳过当前邻格 - 行索引合法的前提下,再校验邻格的列索引是否在当前行的有效列范围内:确认
xx >=0且xx < cells[yy].length - 两层校验全部通过后,再读取对应单元格的值判断死活状态
- 先校验邻格的行索引是否在网格有效行范围内:确认
- 原本依赖
typeof判断越界值的思路方向没问题,但漏了最外层行数组可能不存在的场景,导致防护逻辑写在了已经会触发报错的代码行上,完全失效。
修复后的核心邻格判断逻辑可参考:
if (yy !== y || xx !== x) { // 先校验行是否存在,避免cells[yy]为undefined时直接报错 const row = cells[yy]; if (!row) continue; // 再校验列索引是否在当前行的有效范围内 if (xx < 0 || xx >= row.length) continue; // 校验通过后再读取邻格状态 const neighbourValue = row[xx]; if (neighbourValue === 1) { liveNeighbours++; } else if (neighbourValue === 0) { deadNeighbours++; } }
其他注意事项
- 现有代码里的循环变量
y、x、yy、xx都没有用let/const声明,在非严格模式下会变成全局变量,容易引发变量冲突,建议遍历初始化时加上对应的声明。 - 这种逐层校验索引边界的写法,是二维网格遍历的标准安全实现,比依赖数组越界返回undefined的写法兼容性更强,不会触发引擎类型错误。
内容的提问来源于stack exchange,提问作者SeeBread
相关产品推荐
相关产品推荐

