返回

深入浅出,一探深拷贝与浅拷贝

前端

作为一名技术爱好者,相信您一定对深拷贝与浅拷贝的概念有所耳闻,但您真的理解它们之间的区别并能灵活运用吗?本文将以浅显易懂的方式,结合JavaScript实例为您详细剖析深拷贝与浅拷贝的概念、区别,并揭开对象赋值背后的原理。

剖析深拷贝与浅拷贝的概念

在JavaScript中,复杂类型都存在自己的序列化方法,支持序列化,通过JSON.stringify()序列复杂类型的时候会触发它的序列化方法。然后通过JSON.parse()把这个序列化后的字符串还原成一个对象。一序一转在新的地址生成了新的对象;但是因为对象的序列化方法实现各不相同,所以不同的对象序列化的结果也不同。

浅拷贝 :是指仅复制对象本身的属性值,而不会复制其子属性值。当对浅拷贝的对象进行修改时,不会影响原对象。

深拷贝 :是指不仅复制对象本身的属性值,还会复制其子属性值。当对深拷贝的对象进行修改时,会影响原对象。

揭开对象赋值背后的原理

在JavaScript中,对象赋值的本质是复制变量的引用,而不是复制变量的值。这意味着当您将一个对象赋值给另一个对象时,实际上是将该对象的引用复制给了另一个对象。

举个例子:

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

let obj2 = obj1;

obj2.name = 'Mary';

console.log(obj1.name); // Mary

在这个例子中,当我们将obj1赋值给obj2时,obj2实际上引用了与obj1相同的对象。因此,当我们修改obj2.name时,实际上是修改了obj1的属性值。

深拷贝与浅拷贝的实现

在JavaScript中,我们可以通过多种方式实现深拷贝和浅拷贝。

浅拷贝

实现浅拷贝的简单方法是使用扩展运算符(...)。扩展运算符可以将一个对象的所有属性复制到另一个对象中。

举个例子:

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

let obj2 = { ...obj1 };

obj2.name = 'Mary';

console.log(obj1.name); // John

在这个例子中,我们使用扩展运算符将obj1的所有属性复制到obj2中。因此,当我们修改obj2.name时,不会影响obj1的属性值。

深拷贝

实现深拷贝的一种方法是使用递归函数。递归函数可以遍历对象并复制其所有属性值,包括子属性值。

举个例子:

function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  let newObj = {};

  for (let key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
}

let obj1 = {
  name: 'John',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
  },
};

let obj2 = deepCopy(obj1);

obj2.name = 'Mary';
obj2.address.street = 'Park Avenue';

console.log(obj1.name); // John
console.log(obj1.address.street); // Main Street

在这个例子中,我们使用递归函数deepCopy()obj1进行深拷贝。因此,当我们修改obj2.nameobj2.address.street时,不会影响obj1的属性值。

何时使用深拷贝和浅拷贝

在实际开发中,我们通常会根据具体情况选择使用深拷贝还是浅拷贝。

  • 如果您需要复制一个对象的所有属性值,包括子属性值,那么您应该使用深拷贝。
  • 如果您只需要复制一个对象的浅层属性值,那么您可以使用浅拷贝。

总结

本文详细介绍了深拷贝与浅拷贝的概念、区别,并揭开了对象赋值背后的原理。您应该根据具体情况选择使用深拷贝还是浅拷贝。通过学习本文,希望您能够在开发中更加灵活地运用深拷贝和浅拷贝,从而编写出更加健壮的代码。