forEach回调this指向异常引发TypeError: Cannot read properties of undefined (reading '_matrix')
问题原因
在forEach的普通函数回调里,this的指向不再是Game类的实例,而是变成了undefined(严格模式下),所以无法访问this._matrix。而在fillMatrix方法外层,this正确指向类实例,所以直接修改没问题。
解决方法
方法1:使用箭头函数作为回调
箭头函数不会绑定自己的this,而是继承外层作用域的this,也就是Game实例:
fillMatrix(){ console.log(this._matrix[0][1]) // 0 this._matrix[0][1] = 1 // no errors console.log(this._matrix[0][1]) // 1 this._board.forEach((element, i) => { // 改成箭头函数 if(i < 8){ if(element.classList.contains("infest")){ let row = i / 8; let col = i % 8; this._matrix[parseInt(row)][parseInt(col)] = 1; // 现在可以正常访问 } // 移除i++,forEach会自动迭代索引 } }); return this._matrix; }
方法2:用bind()绑定this到回调函数
通过bind(this)强制让回调里的this指向Game实例:
fillMatrix(){ console.log(this._matrix[0][1]) // 0 this._matrix[0][1] = 1 // no errors console.log(this._matrix[0][1]) // 1 this._board.forEach(function(element, i){ if(i < 8){ if(element.classList.contains("infest")){ let row = i / 8; let col = i % 8; this._matrix[parseInt(row)][parseInt(col)] = 1; // 现在可以正常访问 } // 移除i++ } }.bind(this)); // 绑定当前类实例的this return this._matrix; }
方法3:提前保存this到变量
在回调外把this存到一个变量(比如self),然后在回调里使用这个变量:
fillMatrix(){ console.log(this._matrix[0][1]) // 0 this._matrix[0][1] = 1 // no errors console.log(this._matrix[0][1]) // 1 const self = this; // 保存当前类实例的this到变量 this._board.forEach(function(element, i){ if(i < 8){ if(element.classList.contains("infest")){ let row = i / 8; let col = i % 8; self._matrix[parseInt(row)][parseInt(col)] = 1; // 使用self代替this } // 移除i++ } }); return this._matrix; }
额外注意点
- 代码里的
i++是多余的,forEach会自动遍历每个元素并递增索引,手动修改i会导致逻辑错误,必须删除。 - 当
i < 8时,row = i /8的结果始终是0,parseInt(row)自然也是0,这部分逻辑是否符合你的棋盘坐标计算需求需要确认。
内容的提问来源于stack exchange,提问作者Arsenii Rogozin
相关产品推荐
相关产品推荐

