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

为何两段相似JavaScript代码输出结果不一致?求解析

问题:两段相似JavaScript代码输出不同的原因

期望两段逻辑相似的JavaScript代码得到相同输出,即processedData2最终输出为:

[
  {
    "id": "someid",
    "parts": [
      {
        "part_id": "1"
      }
    ]
  },
  {
    "id": "someid",
    "parts": [
      {
        "part_id": "2"
      }
    ]
  },
  {
    "id": "someid",
    "parts": [
      {
        "part_id": "3"
      }
    ]
  }
]

但示例1未达预期,示例2运行正常,两段代码看似一致,求原因。


示例1(未达预期)

let putData = [
  {
    id: 'someid',
    parts: [
      {
        part_id: '1',
      },
      {
        part_id: '2',
      },
      {
        part_id: '3',
      },
    ],
  },
];
let processedData = [];
for (let i of putData) {
  for (let o in i.parts) {
    processedData.push(i);
  }
}
console.log('processed Data ', processedData);
let processedData2 = processedData;
console.log('processedData 2 before ', processedData2);
for (let i = 0; i < processedData.length; i++) {
  console.log(processedData[i].parts[i]);
  processedData2[i].parts = [processedData[i].parts[i]];
  console.log(processedData2[i].parts[i]);
}
console.log('processedData 2 after', processedData2);

示例2(运行正常)

let processedData = [
  {
    id: 'someid',
    parts: [
      {
        part_id: '1',
      },
      {
        part_id: '2',
      },
      {
        part_id: '3',
      },
    ],
  },
  {
    id: 'someid',
    parts: [
      {
        part_id: '1',
      },
      {
        part_id: '2',
      },
      {
        part_id: '3',
      },
    ],
  },
  {
    id: 'someid',
    parts: [
      {
        part_id: '1',
      },
      {
        part_id: '2',
      },
      {
        part_id: '3',
      },
    ],
  },
];
console.log('processed Data ', processedData);
let processedData2 = processedData;
console.log('processedData 2 before ', processedData2);
for (let i = 0; i < processedData.length; i++) {
  console.log(processedData[i].parts[i]);
  processedData2[i].parts = [processedData[i].parts[i]];
  console.log(processedData2[i].parts[i]);
}
console.log('processedData 2 after', processedData2);

核心原因:引用类型的指向差异

  • 示例1中,processedData数组的3个元素都是同一个对象的引用:循环for (let i of putData) { for (let o in i.parts) { processedData.push(i); } }只是把putData[0]这个对象的引用重复push了3次,数组里的三个元素本质指向内存中同一个对象。
  • 后续修改processedData2[i].parts时,实际是在修改同一个对象的parts属性:第一次循环(i=0)把该对象的parts改成[{part_id: '1'}],第二次循环(i=1)时,processedData[1].parts已经变成了只有1个元素的数组,访问processedData[1].parts[1]会得到undefined,最终导致所有元素的parts都被改成异常值。
  • 示例2中,processedData数组的3个元素是三个独立的对象(结构相同但内存地址不同),修改其中一个对象的parts属性不会影响另外两个,因此能得到预期结果。

示例1的修复方案

每次push时创建原对象的浅拷贝(此处浅拷贝足够),确保数组元素是独立对象:

// 替换原push逻辑
processedData.push({...i, parts: [...i.parts]});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:21:05