类形式实现俄罗斯方块游戏中Object.values()返回首值为NaN的问题排查与解决
Object.values()返回首元素为NaN的问题解决(俄罗斯方块开发场景)
我最近用类实现了一个简易的俄罗斯方块游戏,在调用Object.values()方法时遇到了一个诡异的异常:某方法中调用该函数后,返回结果的第一个值是NaN,但其余值都完全符合预期。
出现问题的代码
问题出在colision_bot()方法中,代码如下:
colision_bot() { let i; console.log(this.falling) let val = Object.values(this.falling); console.log(val) for (i = 0; i < val.length; i++) { if (val[0] == 24 || (this.board[val[0]++][val[1]] == 1 && this._check(val[0]++, val[1]))) { return true } } return false }
其中this.falling是来自以下blocks数组中的某一个元素:
blocks = [ { '1': [1, 4], '2': [2, 4], '3': [3, 4], '4': [4, 4] }, { '1': [1, 4], '2': [2, 4], '3': [3, 4], '4': [3, 5] }, { '1': [1, 5], '2': [2, 5], '3': [3, 4], '4': [3, 5] }, { '1': [1, 4], '2': [2, 4], '3': [2, 5], '4': [3, 5] }, { '1': [1, 5], '2': [2, 4], '3': [2, 5], '4': [3, 4] }, { '1': [1, 4], '2': [1, 5], '3': [2, 4], '4': [2, 5] }, { '1': [1, 4], '2': [2, 4], '3': [2, 5], '4': [3, 4] } ]
控制台日志输出
日志显示this.falling的结构是正常的,但Object.values()返回的数组首元素变成了NaN:
{1: Array(2), 2: Array(2), 3: Array(2), 4: Array(2)} 1: (2) [1, 4] 2: (2) [2, 4] 3: (2) [3, 4] 4: (2) [4, 4] __proto__: Object tetris.js:139 (4) [Array(2), Array(2), Array(2), Array(2)] 0: NaN 1: (2) [2, 4] 2: (2) [3, 4] 3: (2) [4, 4] length: 4
问题解决与原因分析
经过排查,发现核心问题是忽略了数据的嵌套数组结构:
Object.values(this.falling)返回的是一个包含多个长度为2的数组的数组(比如[[1,4], [2,4], ...])- 原代码中错误地直接使用
val[0]和val[1]来访问坐标,而在循环中应该通过val[i][0]和val[i][1]来获取每个方块位置的x、y坐标 - 另外,原代码中的
val[0]++操作会直接修改原数组的元素值,这也是导致首元素变成NaN的直接诱因——当第一次循环时修改了val[0],后续的日志输出就显示该值变成了NaN
修改后的核心逻辑应该将条件中的val[0]替换为val[i][0],val[1]替换为val[i][1],同时注意避免不必要的数组元素自增操作(如果需要判断下一行的位置,应该用val[i][0] + 1而不是直接自增原数组)。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

