JavaScript obj被赋值后值变化问题

博客指出在Js开发中存在内存数据保存不对的问题,以简单代码为例,说明当b指向person.info内存时,person.info重新赋值会使b的值改变。在项目代码量大时此问题不易发现,提出解决办法是重新给person.info赋值为{},让其指向新内存,避免影响b的值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在搞Js的时候发现一个问题,就是内存中保存的数据不对!!

简单举个例子吧,如下:

// 定义一个person对象
var person = {
	info: {
		name: "test"
	}
};
var b = person.info;
// b被赋值为person的info值
console.log(b);
// person.info = {};//如果不想让b的值变化,可以这么写
person.info.name = "Hello";
person.info.age = "18";
console.log(b);

 

输出如下:

{ name: 'test' }
{ name: 'Hello', age: '18' }

从输出的结果中我们发现b的值变化 了,现在代码比较简单,大家发现问题也比较简单,就是b = person.info; 所以当person.info被重新赋值后b也变了!!但是在项目中,代码量比较大,代码位置分散,问题是不容易被发现的。我们可以简单的说b是一个指针,指向person.info的内存。如果我们不想让b的值变化,怎么办?

就是重新给person.info赋值为{}后再操作!

原理就是person.info = {};那么person.info 就指向了一块新内存,而b指向的还是之前的内容,所以再对person.info赋值就不会影响b的值了。

<think>嗯,这个问题看起来是关于JavaScript中对象赋值的。用户想知道当把obj1赋值obj2后,修改obj2的属性会不会影响到obj1。我需要仔细回忆一下JavaScript中的对象赋值机制。 首先,我应该从基本数据类型和引用类型的区别说起。因为基本类型是按传递的,而对象是引用类型。当用户把一个对象赋值给另一个变量时,实际上复制的是对象的引用,而不是对象本身。所以obj1和obj2会指向同一个内存地址。这时候修改其中一个对象的属性,另一个也会跟着变,因为它们引用的是同一个对象。 不过,用户可能会混淆直接修改属性和重新赋值整个对象的情况。比如,如果用obj2 = { ... }这样的方式,这时候obj2会指向一个新对象,而obj1仍然指向原来的对象,这时候修改obj2的属性就不会影响obj1了。所以需要分两种情况讨论:修改属性和重新赋值对象。 另外,可能需要举例子来说明。比如初始的obj1 = {a:1},赋值obj2后,如果修改obj2.a = 2,那么obj1.a也会变成2。但如果将obj2重新赋值为一个新的对象,比如obj2 = {a:3},那么obj1仍然保持原来的。 还有,用户可能对深拷贝和浅拷贝的概念不太清楚,可以提一下如何避免这种引用共享的情况,比如使用Object.assign或者展开运算符进行浅拷贝,或者使用JSON.parse(JSON.stringify())进行深拷贝,不过要注意这些方法的局限性。 总结一下,回答应该分步骤,先讲基本概念,再分情况讨论,最后给出例子和解决方案。这样用户就能清楚理解不同情况下的行为差异了。</think>在JavaScript中,**当对象`obj1`赋值给`obj2`后,修改`obj2`的属性会导致`obj1`同步变化**,但有两种不同场景需要区分: --- ### 一、核心原理(引用类型特性) JavaScript中对象属于**引用类型**,赋值操作本质是复制内存地址的引用关系: ```javascript let obj1 = { name: "Alice" }; let obj2 = obj1; // 此时 obj2 和 obj1 指向同一个内存地址 ``` 此时内存结构为: ``` obj1 → [内存地址A] → { name: "Alice" } ↗ obj2 →───────┘ ``` --- ### 二、两种修改场景的差异 #### 1. **直接修改属性**(会同步) 如果通过属性访问修改: ```javascript obj2.name = "Bob"; // 修改共享内存中的属性 console.log(obj1.name); // 输出 "Bob"(同步变化) ``` 内存变化: ``` obj1 → [内存地址A] → { name: "Bob" } ↗ obj2 →───────┘ ``` #### 2. **整体重新赋值**(不会同步) 如果将`obj2`重新指向新对象: ```javascript obj2 = { name: "Charlie" }; // obj2 指向新内存地址 console.log(obj1.name); // 仍输出 "Bob"(不再关联) ``` 此时内存结构变为: ``` obj1 → [内存地址A] → { name: "Bob" } obj2 → [内存地址B] → { name: "Charlie" } ``` --- ### 三、如何避免同步修改? 若需完全独立的副本,需显式进行拷贝: #### 浅拷贝(仅一层属性) ```javascript const obj2 = Object.assign({}, obj1); // 或展开运算符: const obj2 = { ...obj1 }; ``` #### 深拷贝(嵌套对象) ```javascript const obj2 = JSON.parse(JSON.stringify(obj1)); // 注意:无法处理函数、循环引用等 ``` --- ### 总结表 | 操作类型 | 代码示例 | 是否影响原对象 | |----------------|-----------------------------|----------------| | 修改属性 | `obj2.key = value` | ✅ 会同步 | | 重新赋值对象 | `obj2 = { ... }` | ❌ 不会同步 | | 深拷贝后修改 | `obj2 = cloneDeep(obj1)` | ❌ 不会同步 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值