返回

Object.assign 浅、深拷贝 详解

前端

Object.assign() 是 JavaScript 中非常常用的一个方法,它可以将一个或多个源对象的可枚举属性拷贝到目标对象,让我们一起来深入了解 Object.assign() 的浅拷贝和深拷贝。

浅拷贝

浅拷贝是指只拷贝源对象属性的值,而不拷贝源对象属性的引用。当我们使用 Object.assign() 进行浅拷贝时,如果源对象属性的值是简单类型(string, number, boolean),那么目标对象属性的值将是源对象属性值的副本;如果源对象属性的值是复杂类型(数组, 对象),那么目标对象属性的值将是源对象属性值的引用。

深拷贝

深拷贝是指拷贝源对象属性的值和源对象属性的引用。当我们使用 Object.assign() 进行深拷贝时,如果源对象属性的值是简单类型,那么目标对象属性的值将是源对象属性值的副本;如果源对象属性的值是复杂类型,那么目标对象属性的值将是源对象属性值的副本,而不是源对象属性值的引用。

对于复杂类型的深拷贝,我们需要考虑循环嵌套。

Object.assign() 浅、深拷贝 比较

特性 浅拷贝 深拷贝
拷贝类型 只拷贝源对象属性的值 拷贝源对象属性的值和源对象属性的引用
适用于 简单类型(string, number, boolean) 复杂类型(数组, 对象)
循环嵌套 不需要考虑循环嵌套 需要考虑循环嵌套

Object.assign() 浅、深拷贝 实例

// 浅拷贝
const obj1 = {
  name: 'John',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY'
  }
};

const obj2 = Object.assign({}, obj1);

// 修改 obj2 的属性
obj2.name = 'Mary';
obj2.address.city = 'Los Angeles';

// 打印 obj1 和 obj2
console.log(obj1); // { name: 'John', age: 30, address: { street: 'Main Street', city: 'Los Angeles', state: 'NY' } }
console.log(obj2); // { name: 'Mary', age: 30, address: { street: 'Main Street', city: 'Los Angeles', state: 'NY' } }

// 深拷贝
const obj3 = JSON.parse(JSON.stringify(obj1));

// 修改 obj3 的属性
obj3.name = 'Bob';
obj3.address.city = 'San Francisco';

// 打印 obj1 和 obj3
console.log(obj1); // { name: 'John', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }
console.log(obj3); // { name: 'Bob', age: 30, address: { street: 'Main Street', city: 'San Francisco', state: 'NY' } }

总结

在 JavaScript 中,Object.assign() 方法可以实现浅拷贝和深拷贝。浅拷贝只拷贝源对象属性的值,而不拷贝源对象属性的引用。深拷贝拷贝源对象属性的值和源对象属性的引用。对于简单类型,浅拷贝和深拷贝的结果是一样的。对于复杂类型,浅拷贝只拷贝一层,而深拷贝会拷贝所有的层级。在实际开发中,根据需要选择使用浅拷贝还是深拷贝。