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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:52:38