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

为何数组objArr中反复出现同一对象,且推入的多对象值均相同?

为什么数组里反复出现同一个对象?

这种情况我在开发中碰到过好多次,核心原因其实是你每次推入数组的都是同一个对象的引用,而不是新创建的独立对象。

在JavaScript里,对象属于「引用类型」,和字符串、数字这类「值类型」不一样:

  • 值类型赋值时,会直接复制一份具体的值;
  • 引用类型赋值时,复制的是指向对象的内存地址,而不是对象本身。

举个错误代码的例子,你大概率是这么写的:

const objArr = [];
// 只在循环外创建了一个对象
const tempObj = {};

for (let i = 0; i < 3; i++) {
  // 每次循环只是修改这个对象的属性
  tempObj.id = i;
  tempObj.name = `Item ${i}`;
  // 推入数组的都是同一个tempObj的引用
  objArr.push(tempObj);
}

console.log(objArr);
// 输出结果:三个对象全是 {id: 2, name: "Item 2"}

为什么会这样?因为tempObj只被创建了一次,所有循环里的修改都是在同一个对象上操作,数组里的每一项都指向这个唯一的对象。当循环结束时,对象的属性是最后一次修改的值,所以数组里所有项看起来都一模一样。

解决方法

要解决这个问题,核心就是每次推入数组时,都创建一个新的对象实例,常见的两种方式:

1. 在循环内部创建新对象

把对象的创建逻辑放到循环里,确保每次迭代都生成一个全新的对象:

const objArr = [];

for (let i = 0; i < 3; i++) {
  // 每次循环都新建一个对象
  const tempObj = {};
  tempObj.id = i;
  tempObj.name = `Item ${i}`;
  objArr.push(tempObj);
}

console.log(objArr);
// 输出三个独立的对象:[{id:0,...}, {id:1,...}, {id:2,...}]

2. 基于模板对象创建新实例

如果你需要基于某个基础模板对象生成新对象,可以用扩展运算符...或者Object.assign()来实现浅复制,生成新对象:

const objArr = [];
// 基础模板对象
const baseObj = { type: "default", status: "active" };

for (let i = 0; i < 3; i++) {
  // 复制模板属性,同时添加/覆盖新属性,生成新对象
  const newObj = { ...baseObj, id: i, name: `Item ${i}` };
  objArr.push(newObj);
}

console.log(objArr);
// 每个对象都是独立实例,模板属性保留,id和name各自不同

注意:如果模板对象有嵌套的子对象,浅复制会导致子对象还是共享引用,这时候需要用深复制(比如JSON.parse(JSON.stringify(baseObj))或者自定义递归深复制函数)。

总结

本质就是要区分「引用类型」和「值类型」的差异,确保数组里的每一项都是独立的对象实例,而不是指向同一个对象的引用。只要每次推入数组时都新建对象,就能解决这个问题啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:47:10