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

JavaScript变量赋值结果与预期不符的问题排查求助

问题分析与解决方案

核心问题1:所有宝可梦对象共享同一个引用

你遇到的所有宝可梦条目都显示最后一只Cinderace数据的问题,根源在于JavaScript中对象是引用类型。你在代码里一直复用同一个pokemonTemplate对象,没有为每只宝可梦创建独立的新对象副本。

看这段代码:

var blankTemplate = pokemonTemplate;
// 后续直接将 pokemonTemplate 赋值给 parsedTeams 的各个位置

这里blankTemplate只是pokemonTemplate的引用,不是全新对象。每次修改pokemonTemplate的属性时,所有指向它的引用都会同步更新,最终所有位置只会保留最后一次修改的结果。

核心问题2:console.log的延迟解析特性

你提到第3行刚声明parsedTeams就打印,但结果和最终返回值一致,这是浏览器控制台的特性:console.log对于引用类型(对象/数组),显示的是你展开查看时的对象状态,不是调用console.log时的瞬时状态。当你后续修改这个对象时,控制台里的日志会跟着更新,看起来像是“提前”显示了最终结果。

修复方案

1. 为每只宝可梦创建独立的模板对象

不要复用同一个模板,每次需要新宝可梦时,通过函数生成全新的模板对象:

// 封装模板创建函数,每次调用都返回新对象
function getNewPokemonTemplate() {
  return { 
    "pokemon" : "", 
    "name" : "", 
    "item" : "", 
    "ability": "", 
    "moves": { "1" : "", "2" : "", "3" : "", "4" : "" }, 
    "nature" : "", 
    "evs" : "", 
    "gender" : "", 
    "ivs" : "", 
    "shiny" : "", 
    "level" : "", 
    "happiness" : "" 
  };
}

然后在需要新宝可梦的位置替换原有的赋值:

// 替换原有的 parsedTeams[data][teamCount].team[1] = blankTemplate;
parsedTeams[data][teamCount].team[1] = getNewPokemonTemplate();

2. 解决console.log的“提前显示”问题

如果想查看对象在某个时刻的真实快照,可以将对象转为JSON字符串再打印:

console.log(JSON.parse(JSON.stringify(parsedTeams)));

这样打印的是调用时的对象状态,不会随后续修改变化。

其他代码修正点

  • 修复语法错误:parsedTeams[gen][pokemonCount], pokemonTemplate = blankTemplate; 中的逗号是错误写法,改为创建新模板对象的赋值
  • 声明循环变量i时加上let,避免成为全局变量
  • 调整宝可梦计数逻辑,确保每只宝可梦对应到所属团队的正确位置

关键修正后的代码片段

function ParseTeams(rawTeams){
  const parsedTeams = {};
  // 打印对象快照,避免控制台延迟更新
  console.log(JSON.parse(JSON.stringify(parsedTeams)));
  const rawLines = rawTeams.split("\n");
  const teamTemplate = { "name" : "", "team": {} };

  function getNewPokemonTemplate() {
    return { 
      "pokemon" : "", 
      "name" : "", 
      "item" : "", 
      "ability": "", 
      "moves": { "1" : "", "2" : "", "3" : "", "4" : "" }, 
      "nature" : "", 
      "evs" : "", 
      "gender" : "", 
      "ivs" : "", 
      "shiny" : "", 
      "level" : "", 
      "happiness" : "" 
    };
  }

  for(let i = 0; i < rawLines.length; i++) {
    let data = "";
    let pokemonCount = 0;
    let teamCount = 1;
    let dataCount = 0;
    let nextIsMon = false;
    let gen, teamName;
    const currentLine = rawLines[i];
    
    for(let c of currentLine) {
      if(c == "]" && !nextIsMon) { 
        if(pokemonCount == 0){ 
          if(!parsedTeams[data]){
            parsedTeams[data] = {};
          }
          // 为团队创建新模板副本
          parsedTeams[data][teamCount] = {...teamTemplate};
          // 为第一只宝可梦创建新对象
          parsedTeams[data][teamCount].team[1] = getNewPokemonTemplate();
          gen = data;
          data = "";
          pokemonCount++;
          nextIsMon = true;
          continue;
        }
      } else if(c == "]" && nextIsMon) {
        // 为当前宝可梦创建新对象并赋值
        parsedTeams[gen][teamCount].team[pokemonCount] = getNewPokemonTemplate();
        pokemonCount++;
        dataCount = 1;
        continue;
      } else if(c == "|") {
        switch(dataCount){
          case(0):
            parsedTeams[gen][teamCount].name = data;
            teamName = data;
            break;
          case(1):
            // 操作当前团队的当前宝可梦对象
            const currentPokemon = parsedTeams[gen][teamCount].team[pokemonCount];
            currentPokemon.pokemon = data;
            console.log(data);
            console.log(JSON.parse(JSON.stringify(parsedTeams[gen])));
            break;
          // 其余case同理,都操作当前宝可梦对象而非全局模板
          case(2):
            parsedTeams[gen][teamCount].team[pokemonCount].name = data;
            break;
          case(3):
            parsedTeams[gen][teamCount].team[pokemonCount].item = data;
            break;
          // ... 剩余case按此逻辑修改
          default:
            console.log("count out of bounds");
        };
        dataCount++;
        data = "";
      } else {
        data += c;
      }
    }
    pokemonCount = 0;
    teamCount++;
    data = "";
    nextIsMon = false;
  }
  return parsedTeams;
}

修改后每只宝可梦都是独立对象,不会互相覆盖,console.log也能正确显示瞬时状态。

内容的提问来源于stack exchange,提问作者user16268191

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:22:28