返回

详解浅拷贝和深拷贝,前后端面试时必须知道的知识

前端

浅拷贝

浅拷贝只拷贝对象本身,不会拷贝对象中的属性。当我们对浅拷贝对象进行修改时,不会影响原对象。

const obj1 = {
  name: 'John Doe',
  age: 30
};

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

obj2.name = 'Jane Doe';

console.log(obj1); // { name: 'John Doe', age: 30 }
console.log(obj2); // { name: 'Jane Doe', age: 30 }

从上面的例子中,我们可以看到,当我们修改 obj2 的 name 属性时,obj1 的 name 属性并没有改变。这是因为 obj2 是 obj1 的浅拷贝,它只拷贝了 obj1 的属性值,而并没有拷贝 obj1 的属性本身。

深拷贝

深拷贝不仅拷贝对象本身,还会拷贝对象中的所有属性,包括嵌套对象。当我们对深拷贝对象进行修改时,不会影响原对象。

const obj1 = {
  name: 'John Doe',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

const obj2 = JSON.parse(JSON.stringify(obj1));

obj2.name = 'Jane Doe';
obj2.address.street = '456 Elm Street';

console.log(obj1); 
// { 
//   name: 'John Doe', 
//   age: 30, 
//   address: {
//     street: '123 Main Street',
//     city: 'Anytown',
//     state: 'CA',
//     zip: '12345'
//   }
// }

console.log(obj2); 
// { 
//   name: 'Jane Doe', 
//   age: 30, 
//   address: {
//     street: '456 Elm Street',
//     city: 'Anytown',
//     state: 'CA',
//     zip: '12345'
//   }
// }

从上面的例子中,我们可以看到,当我们修改 obj2 的 name 属性和 address.street 属性时,obj1 的 name 属性和 address.street 属性并没有改变。这是因为 obj2 是 obj1 的深拷贝,它拷贝了 obj1 的所有属性,包括嵌套对象。

浅拷贝与深拷贝的优缺点

浅拷贝和深拷贝都有各自的优缺点。浅拷贝的优点是速度快,内存占用少。深拷贝的优点是更安全,不会影响原对象。

在实际开发中,我们应该根据具体情况选择使用浅拷贝还是深拷贝。如果我们只需要拷贝对象本身,而不关心对象中的属性,那么可以使用浅拷贝。如果我们需要拷贝对象及其所有属性,包括嵌套对象,那么可以使用深拷贝。

常见的浅拷贝和深拷贝实现方法

除了 Object.assign() 和 JSON.parse(JSON.stringify()) 之外,还有很多其他的方法可以实现浅拷贝和深拷贝。

浅拷贝

  • Object.create() :创建一个新对象,并指定另一个对象为其原型。
  • Spread operator :使用展开运算符(...)可以将一个对象的属性拷贝到另一个对象。

深拷贝

  • JSON.parse(JSON.stringify()) :将对象转换为 JSON 字符串,然后将 JSON 字符串解析回对象。
  • Lodash :Lodash 是一个 JavaScript 库,它提供了很多有用的函数,包括深拷贝函数。
  • 递归 :我们可以使用递归来实现深拷贝。

总结

浅拷贝和深拷贝是 JavaScript 中两个重要的概念。它们的区别在于浅拷贝只拷贝对象本身,而深拷贝则拷贝对象及其所有属性,包括嵌套对象。在实际开发中,我们应该根据具体情况选择使用浅拷贝还是深拷贝。