You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript二维grid数组索引访问undefined赋值报错排查

网格赋值报错问题排查与修复

相关实现代码

class Space {
  constructor(x, y, c = 'grey',c2 = 'darkgrey') {
    this.x = x;
    this.y = y;
    this.w = 10;
    this.h = 10;
    this.c = c;
    this.c2 = c2;
  }
  draw() {
    drawSpace(this.x,this.y,this.c,this.c2)
  }
}
 
// Creates grid for movement
function createGrid() {
  for (let i = 0; i < 80; i+=1) {
    let tempArr = [];
    for (let j = 0; j < 40; j+=1) {
      tempArr.push(new Space(i,j));
    }
    grid.push(tempArr);    
  }
  grid[0][0] = pathfinder;
  grid[79][0] = target;
}

//draws grid
grid.forEach(function(e) {
  e.forEach(function(f) {
    f.draw();
  });
});
  • 代码中pathfinder、target为预先定义的Space类实例,分别配置了绿色、红色的专属样式,相关实现未在上述代码中展示。
  • 异常表现:执行数组索引赋值操作时抛出「无法设置undefined的属性(设置'0')」错误:
    • 最初发现grid[80][0] = target;语句触发报错,已知80为越界索引(循环生成的grid外层数组索引范围为0-79)
    • 后续排查发现非越界的grid[1][0]位置赋值也会触发同类报错
    • 通过console.log打印对应索引位置可以看到初始for循环生成的基础Space对象,但始终无法完成自定义实例的赋值操作

问题核心成因

报错本质是尝试给undefined值设置属性,对应两个根因:

  1. 初始化逻辑未按顺序执行:代码只定义了createGrid函数,但没有在赋值、遍历操作前调用它。此时grid要么是未填充任何子数组的空数组,要么是未定义值,访问grid[0]、grid[1]得到的都是undefined,自然无法执行[0] = xxx的赋值操作。控制台打印能看到基础Space对象,是因为控制台对引用类型的打印是延迟解析的——执行打印语句时数组还没完成填充,等手动点开控制台查看结果时,之前调试手动触发的网格生成逻辑已经把内容填进去了,不代表代码运行到赋值行时数组已经初始化完成。
  2. 索引越界:外层循环i的取值范围是0-79,最终生成的grid外层数组长度为80,合法索引范围是0-79,grid[80]本身是不存在的undefined,无论初始化是否完成,给grid[80][0]赋值都会触发同类错误。

修复方案

按执行顺序调整逻辑即可:

  • 提前在全局作用域声明grid为空数组,避免作用域异常
  • 所有对grid的赋值、遍历绘制操作,必须放在createGrid()调用完成之后执行,不要把操作逻辑散落在全局作用域提前运行
  • 修正越界索引:如果确实需要把target放在第80列位置,就把外层循环的上限从80调整为81,保证对应索引的子数组存在;如果不需要就把target的赋值索引改成79以内的合法值

修复后的核心参考代码:

// 提前全局初始化网格数组
let grid = [];
// 提前定义起点、终点实例
const pathfinder = new Space(0, 0, 'green', 'darkgreen');
const target = new Space(79, 0, 'red', 'darkred');

class Space {
  constructor(x, y, c = 'grey',c2 = 'darkgrey') {
    this.x = x;
    this.y = y;
    this.w = 10;
    this.h = 10;
    this.c = c;
    this.c2 = c2;
  }
  draw() {
    drawSpace(this.x,this.y,this.c,this.c2)
  }
}
 
// 生成网格
function createGrid() {
  // 每次生成前清空原有网格,避免重复生成叠加
  grid = [];
  for (let i = 0; i < 80; i+=1) {
    let tempArr = [];
    for (let j = 0; j < 40; j+=1) {
      tempArr.push(new Space(i,j));
    }
    grid.push(tempArr);    
  }
  // 网格生成完成后再替换指定位置元素
  grid[0][0] = pathfinder;
  grid[79][0] = target;
}

// 先执行网格初始化
createGrid();

// 初始化完成后再执行绘制
grid.forEach(function(e) {
  e.forEach(function(f) {
    f.draw();
  });
});

内容的提问来源于stack exchange,提问作者Nate Baker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:57:25