JavaScript变量存储异常:动态对象存入数组后值被覆盖
问题分析与解决方案
这是一个典型的引用类型赋值导致的坑,我来帮你把问题拆解明白,再给出靠谱的修复方案:
问题根源
你在循环外(或者j循环的外层)只创建了一个objNum对象,数组scoreNum里存储的其实都是这个对象的引用。每次循环修改objNum.result和objNum.title时,都是在修改同一个对象的属性——相当于你拿着同一个瓶子反复装不同的水,最后所有数组元素指向的都是最后一次装水的那个瓶子。
你后来尝试在循环末尾重置objNum = {title: "", result: 0},但大概率是重置的位置不对(比如放在了内部i循环的末尾),导致j循环依然在复用同一个对象引用,所以问题没解决。
修复后的代码
我帮你调整了变量作用域和逻辑顺序,既解决了引用覆盖问题,还修复了隐藏的数值累加错误:
// 假设scoreNum是预先声明的空数组 const scoreNum = []; for (let j = 0; j < array.length; j++) { // 关键:每次j循环都创建一个全新的对象实例 const objNum = { title: "", result: 0 }; // 把result放到j循环内部,避免不同j之间的数值累加 let result = 0; for (let i = 0; i < 6; i++) { /* 从HTML页面获取结果数值(示例:8/10,结果为8)*/ const currentScore = j === 0 ? Number(score[i].innerHTML.replace('/10', '')) : Number(score[i + (x * j)].innerHTML.replace('/10', '')); result += currentScore; } // 计算平均值应该在6个分数累加完成后,而不是每次i循环都计算 const averageResult = (Math.round((result / 6) * 10)) / 10; objNum.result = averageResult; objNum.title = title[j].innerHTML; scoreNum.push(objNum); // 用push更直观,当然用scoreNum[j] = objNum也可以 console.log(objNum); } console.log(scoreNum); // 现在会输出7个不同的对象
核心修改点
- 每次
j循环创建新对象:把objNum的声明移到j循环内部,确保数组里的每个元素都是独立的对象引用,不会互相覆盖。 - 修正
result的作用域:把result放到j循环内部,避免不同j循环之间的数值累加(你原来的代码里result应该是全局或外层作用域的,会导致每次j循环都叠加之前的结果,这是另一个隐藏bug)。 - 调整平均值计算时机:原来的代码每次
i循环都会重新计算平均值,这会导致结果错误——应该等6个分数全部累加完成后,再计算一次平均值。
关于“重启电脑后问题消失”的小插曲
这种情况大概率是缓存或代码执行环境的临时异常,比如浏览器缓存了旧代码,或者某次执行时变量作用域意外符合了预期,但这不是根本解决办法,上面的代码调整才是彻底修复问题的方式。
内容的提问来源于stack exchange,提问作者Siro
相关产品推荐
相关产品推荐

