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

复制ArrayList后修改原列表为何同步影响副本?技术咨询

为什么修改options数组的对象时,optionsListDuplicate也会跟着变?

嗨,这个问题其实是JavaScript里引用类型的经典陷阱,我来给你理清楚背后的逻辑~

问题本质:引用类型的浅拷贝

在JavaScript中,对象(包括你创建的{ label:..., value:... }这种字面量对象)属于引用类型。当你把一个对象添加到数组里时,数组存储的并不是这个对象本身,而是这个对象在内存中的地址引用。

如果你的实际代码中是先创建一个对象,再把它同时推入两个数组(比如下面这种写法):

// 错误示例:同一个对象被推入两个数组
for(let i=0;i<data.length;i++){ 
  const item = { label:data[i].name, value:data[i].id };
  this.options.push(item); 
  this.optionsListDuplicate.push(item); // 这里推的是同一个对象的引用
}

那options和optionsListDuplicate的对应位置存储的都是同一个对象的内存引用。此时不管你从哪个数组里修改这个对象的属性(比如this.options[0].label = "新名称"),实际修改的是内存中那个唯一的对象,另一个数组自然会同步看到变化。

怎么解决?创建独立的对象副本

要让两个数组里的对象互不影响,你需要确保每个数组里的对象都是独立的副本,而不是同一个引用。针对你这种单层结构的对象(只有label和value两个字符串属性),有几种简单的方法:

  1. 使用对象展开运算符:
for(let i=0;i<data.length;i++){ 
  const originalItem = { label:data[i].name, value:data[i].id };
  this.options.push({...originalItem }); // 创建新对象副本
  this.optionsListDuplicate.push({...originalItem }); // 另一个新副本
}
  1. 使用Object.assign:
for(let i=0;i<data.length;i++){ 
  const originalItem = { label:data[i].name, value:data[i].id };
  this.options.push(Object.assign({}, originalItem));
  this.optionsListDuplicate.push(Object.assign({}, originalItem));
}
  1. 直接在push时创建新对象:
    其实你最开始的写法就是这种思路——每次push时都用对象字面量创建全新的对象,只要确保没有复用之前创建的对象,就不会出现引用共享的问题。

如果你的对象是多层嵌套的(比如label本身又是一个对象),那上面的浅拷贝方法就不够了,需要用深拷贝,比如递归实现深拷贝,或者使用JSON.parse(JSON.stringify(originalItem))(注意这种方法无法拷贝函数、Symbol等特殊类型)。

额外提醒:数组本身的复制

如果你是直接把数组赋值给另一个变量(比如this.optionsListDuplicate = this.options),那两个变量会指向同一个数组的引用,不管你修改数组的元素还是数组本身(比如push、pop、splice),另一个变量都会同步变化。这种情况要复制数组,应该用:

  • 展开运算符:this.optionsListDuplicate = [...this.options]
  • slice()方法:this.optionsListDuplicate = this.options.slice()
  • Array.from():this.optionsListDuplicate = Array.from(this.options)
    但同样,这些都是浅拷贝,数组里的对象还是引用类型,需要结合上面的对象拷贝方法一起用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:23:47