JavaScript中Array push方法异常:元素丢失问题求助
问题分析:为什么["54", "43"]会从结果中丢失?
先直接说核心问题:你的代码里存在未声明的全局变量,这会导致不可预测的变量覆盖,同时DOM判断的逻辑也有潜在漏洞,这两个点结合起来可能就是你遇到的问题根源。
1. 全局变量污染是最大隐患
你代码里的coin、positions、freeLocation都没有用let/const声明,会自动变成全局变量。虽然这个函数是同步执行的,但全局变量很容易被其他代码(甚至函数内部的后续循环)意外覆盖。比如:
- 当第二次外层循环(处理"54"棋子)时,
coin被赋值为"54",但如果有其他全局逻辑修改了coin,就会导致push到数组里的值出错。 - 虽然在你的场景里看起来同步执行不会有问题,但这是非常危险的编码习惯,也是很多诡异bug的源头。
2. DOM元素判断的潜在漏洞
你用if (cell.innerHTML == '')判断单元格是否为空,但这里有两个问题:
- 如果
document.getElementById(positions[j])找不到元素,cell会是null,调用innerHTML会直接报错,导致后续代码无法执行(可能会跳过["54", "43"]的处理)。 - 单元格里如果有空格、换行符这类空白字符,
innerHTML == ''会判断为非空,但实际上单元格是“空”的。
为什么调试时加j就会出现?
当你改成freeLocations.push(freeLocation, j)时,数组内容从["54","43"]变成了["54","43",0],这可能:
- 让你在控制台里更容易区分重复内容的数组(比如["52","43"]和["54","43"]看起来很像,你可能误以为其中一个没被添加);
- 或者因为修改了数组结构,避开了某些隐性的控制台显示bug(比如浏览器控制台延迟显示数组内容,导致你看到的不是push时的真实状态)。
修复后的代码
我帮你把代码里的问题都修正了,你可以直接测试:
function checkFreeLocations(coins){ let allFreePostions = []; // 没用的变量可以考虑删除,比如dangerPosition for (let i = 0; i < coins.length; i++){ // 用const声明不会修改的变量 const coin = coins[i][0]; const positions = coins[i][1]; for (let j = 0; j < positions.length; j++){ const freeLocations = []; const cell = document.getElementById(positions[j]); // 先判断元素存在,再用trim()处理空白字符 if (cell && cell.innerHTML.trim() === ''){ const freeLocation = positions[j]; freeLocations.push(coin); freeLocations.push(freeLocation); allFreePostions.push(freeLocations); // 调试用:立即打印,避免控制台延迟显示的坑 console.log('已添加:', [...freeLocations]); } } } // 增加return,方便获取结果 return allFreePostions; } // 调用并查看结果 const result = checkFreeLocations([["52", ["41", "43", "61", "63"]], ["54", ["43", "45", "63", "65"]]]); console.log('最终结果:', result);
修复点说明
- 所有变量都用
let/const声明,彻底避免全局污染; - 增加
cell存在的判断,防止找不到元素时报错; - 用
innerHTML.trim() === ''替代原判断,正确识别空白单元格; - 添加
return语句,方便直接获取函数执行结果; - 增加调试用的
console.log,在push时立即打印,确保你看到的是真实添加的内容。
内容的提问来源于stack exchange,提问作者Abraham G.
相关产品推荐
相关产品推荐

