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

JavaScript中修改变量导致另一变量同步变化的原因及解决方法

问题复现代码
let a=['one','two'];
let b=a;
b.push('three')

console.log(a,b);

运行上述代码时,执行b.push('three')修改b的取值后,变量a的值也会同步改变。

现象根本原因

JavaScript的数据类型分为两类:原始类型(数字、字符串、布尔值等)和引用类型(数组、普通对象、函数等)。

  • 原始类型的值直接存储在栈内存中,变量赋值时会直接复制完整的值,两个变量后续修改互不干扰。
  • 引用类型的实际数据存储在堆内存中,变量本身只存储指向堆内存对应数据的引用地址。

代码中执行let b = a时,并没有在内存中创建新的数组,只是把a存储的数组引用地址复制了一份给b,a和b两个变量指向堆内存里完全相同的数组实例。此时不管通过哪个变量修改数组内容,本质都是修改同一块内存空间里的数据,两个变量访问到的结果自然会同步变化。

最高效解决方法

根据数组的结构不同,选择对应方案即可:

  • 如果是一维数组,元素全为原始类型,直接用展开运算符做浅拷贝即可,写法简洁且V8等主流JS引擎对该语法的优化程度极高,性能表现最好:
let a = ['one','two'];
let b = [...a]; // 生成全新的数组实例,和a指向不同内存地址
b.push('three');
console.log(a, b); // a: ['one','two'],b: ['one','two','three'],两者互不影响
  • 如果数组存在嵌套引用类型元素(比如数组项包含对象、其他子数组),且运行环境支持ES2022+(所有现代浏览器、Node.js 11及以上版本),直接用原生structuredClone()方法做深拷贝,性能远优于手动递归、JSON.parse(JSON.stringify())等方案,还支持处理循环引用、Date、RegExp等特殊类型,不会出现数据丢失问题:
let a = ['one', 'two', { label: 'demo' }];
let b = structuredClone(a);
b[2].label = 'changed';
console.log(a[2].label); // 仍然输出'demo',不受b的修改影响

注意:JSON.parse(JSON.stringify(a))的方案存在明显缺陷,会丢失undefined、Symbol、函数等类型的值,也无法处理循环引用,性能表现差,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:39:19