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

JS中修改对象数组指定索引属性时全部属性被修改的问题排查

修改对象数组时所有元素属性同步变化的问题

问题根源

你代码里的数组options中,两个元素其实是同一个对象的引用。因为你只创建了一个va对象,连续两次调用options.push(va)时,只是把这个对象的内存地址添加到数组的两个位置,并不是创建了两个独立的对象。所以当你修改options[0].stat['abc']时,本质是修改了那个唯一的va对象的属性,数组里的另一个元素因为指向同一个对象,自然也会显示相同的变化。

解决方案(直接更新原数组)

要让数组中的对象相互独立,必须确保每次添加到数组的是新的对象实例,而不是复用同一个引用。以下是几种可行的方式:

方式1:直接创建独立对象

如果对象结构简单,直接手动创建多个独立的对象:

let options = [];
// 创建第一个独立对象
let va1 = {
  stat: {
    cde: null,
    abc: null,
  },
};
// 创建第二个独立对象
let va2 = {
  stat: {
    cde: null,
    abc: null,
  },
};
options.push(va1);
options.push(va2);

// 修改第一个对象的属性
options[0].stat['abc'] = 'test';
console.log(options);
// 此时只有第一个对象的abc为'test',第二个保持null

方式2:深拷贝生成新对象

如果需要基于现有对象生成独立副本,因为你的对象包含嵌套属性(stat也是对象),必须使用深拷贝来确保所有层级的属性都是独立的:

let options = [];
let va = {
  stat: {
    cde: null,
    abc: null,
  },
};
// 用JSON序列化/反序列化实现深拷贝(适合无函数、Symbol等特殊类型的简单对象)
options.push(JSON.parse(JSON.stringify(va)));
options.push(JSON.parse(JSON.stringify(va)));

options[0].stat['abc'] = 'test';
console.log(options);

方式3:使用结构化克隆(现代环境推荐)

现代浏览器和Node.js支持structuredCloneAPI,它能处理更多类型(比如Date、Map等),比JSON方法更可靠:

let options = [];
let va = {
  stat: {
    cde: null,
    abc: null,
  },
};
options.push(structuredClone(va));
options.push(structuredClone(va));

options[0].stat['abc'] = 'test';
console.log(options);

关键总结

  • JavaScript中对象、数组属于引用类型,赋值或push操作传递的是内存地址,不是对象本身
  • 要让数组元素独立,必须为每个元素创建新的对象实例
  • 嵌套对象需要用深拷贝,浅拷贝(比如{...va})只能拷贝顶层属性,嵌套的stat还是同一个引用,修改后依然会影响所有副本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:25:20