为何将变量中的对象赋值给另一变量后,修改其一两者均改变?
这不是Bug,是JavaScript对象的引用特性!
兄弟,这绝对不是Bug,而是JavaScript里对象(包括数组、函数这类引用类型)最核心的特性之一——引用赋值,咱们一步步拆解你的代码就能彻底搞懂:
先看你写的代码:
var obj1 = {test:0}; var obj2 = obj1; obj2.test= 2; console.log(obj1,obj2);
咱们逐行分析背后的逻辑:
- 第一行
var obj1 = {test:0};:JavaScript会在内存中创建一个{test:0}的对象实例,但obj1这个变量并没有直接存储这个对象本身,而是存了指向这个对象的内存地址(也就是引用)。 - 第二行
var obj2 = obj1;:这一步不是把obj1的对象复制一份给obj2,而是把obj1手里的那个内存地址(引用)复制给了obj2。现在obj1和obj2就像两把钥匙,开的是同一扇门(同一个内存里的对象)。 - 第三行
obj2.test= 2;:你通过obj2这个“钥匙”打开门,修改了对象的test属性——这其实直接修改了内存里那个唯一的对象本身。 - 最后
console.log的时候,obj1和obj2指向的都是被修改后的那个对象,所以输出自然都是{test:2}。
如果你想达到你预期的{test:0} {test:2}效果,就得给obj2创建一个新的对象实例,而不是共用同一个引用。常用的方法有这几种:
- 对象展开语法(ES6+):
var obj1 = {test:0}; var obj2 = {...obj1}; // 复制obj1的所有属性到新对象 obj2.test= 2; console.log(obj1,obj2); // 输出 {test:0} {test:2}
- 使用
Object.assign:
var obj1 = {test:0}; var obj2 = Object.assign({}, obj1); // 把obj1的属性合并到空对象,得到新对象 obj2.test= 2; console.log(obj1,obj2);
- 如果是嵌套对象,还需要深拷贝(比如递归实现或者用
JSON.parse(JSON.stringify(obj1)),但后者对函数、Symbol等类型有局限性)。
内容的提问来源于stack exchange,提问作者Facundo Silva
相关产品推荐
相关产品推荐

