JS关于Object.assign()和浅拷贝、深拷贝

什么是浅拷贝和深拷贝

  • js中存对象都是存地址的,浅拷贝指向的是同一块内存区块,深拷贝则是另外开辟了一块区域。

两个例子

var obj1 = { num: 100, str: 'abc' }
var obj2 = obj1
obj2.num = 200
console.log(obj1, obj2)  
打印结果:两个对象数据内容相同,因为是浅拷贝,两个对象指向同一内存区域
var obj1 = { num: 100, str: 'abc' }
var obj2 = deepCopy(obj1)
obj2.num = 200
console.log(obj1, obj2)
打印结果:两个对象数据内容不相同,num分别是100,200,这是深拷贝,两个对象指向内存地址不同

Object.assign()

  • 对象的静态方法,可以复制对象的可枚举属性到目标对象,实现对象属性的合并
var obj1 = {
    name: 'Jack',
    age: 31,
}
var obj2 = Object.assign(obj1, { age: 21, sex: 1 })
console.log(obj1)  // name: 'Jack', age: 21, sex: 1
  • 相同的属性,目标对象会被源对象覆盖。多个源对象时,存在相同属性,后面源对象覆盖前面的源对象
  • Object.assign()只是比浅拷贝多一层深拷贝而已,只能对单层的对象进行深拷贝,也就是对象里面的属性都是基本类型,没有嵌套
var obj2 = Object.assign({}, obj1)
如果obj1中都是基本类型则可以实现深拷贝
如果里面有Object类型,则obj2、obj1中的Object属性会一同变化
JavaScript 中的 `Object.assign()` 扩展运算符(`...`)均执行的是**浅拷贝**,而非深拷贝。这意味着它们在拷贝对象时,仅复制对象的第一层属性。如果属性值是引用类型(如对象或数组),则复制的是该值的引用地址,而非其实际内容。 ### `Object.assign()` 的拷贝行为 `Object.assign(target, ...sources)` 方法将一个或多个源对象的可枚举属性复制到目标对象中。它会直接修改目标对象并返回它。对于嵌套对象的属性,`Object.assign()` 仅复制引用,不会创建嵌套对象的副本。例如: ```javascript const source = { a: { b: 1 } }; const target = {}; Object.assign(target, source); console.log(target.a === source.a); // true,说明复制的是引用 ``` ### 扩展运算符(`...`)的拷贝行为 扩展运算符通过 `{ ...obj }` 创建一个新对象,并将源对象的可枚举属性复制到新对象中。与 `Object.assign()` 一样,它也仅执行浅拷贝。例如: ```javascript const source = { a: { b: 1 } }; const copy = { ...source }; console.log(copy.a === source.a); // true,说明复制的是引用 ``` ### 为什么是浅拷贝浅拷贝仅复制对象的第一层属性。对于基本类型的属性值,复制的是实际值;而对于引用类型的属性值(如嵌套对象),复制的是内存地址。因此,当嵌套对象被修改时,拷贝后的对象也会受到影响[^1]。例如: ```javascript const original = { a: { b: 1 } }; const copy = { ...original }; copy.a.b = 2; console.log(original.a.b); // 输出 2,说明原对象的嵌套属性被修改 ``` ### 如何实现深拷贝? 如果需要拷贝嵌套对象的所有层级,需使用深拷贝方法: 1. **使用 `JSON.parse(JSON.stringify(obj))`** 此方法通过序列化对象为 JSON 字符串,再解析字符串生成新对象。它适用于不含函数循环引用的对象: ```javascript const deepCopy = JSON.parse(JSON.stringify(original)); ``` 2. **使用递归函数** 递归遍历对象的所有层级,并为每个属性创建新对象或数组: ```javascript function deepClone(obj) { if (typeof obj !== 'object' || obj === null) return obj; let copy = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { copy[key] = deepClone(obj[key]); } } return copy; } ``` 3. **使用第三方库** 常用的库如 Lodash 提供了 `_.cloneDeep()` 方法实现深拷贝: ```javascript const _ = require('lodash'); const deepCopy = _.cloneDeep(original); ``` ### 总结 `Object.assign()` 扩展运算符(`...`)均执行浅拷贝,适用于简单对象的复制。如果对象包含嵌套结构,需要使用深拷贝方法(如 `JSON.parse(JSON.stringify(obj))`、递归函数或第三方库)以避免引用共享问题[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值