返回

以通俗易懂的方式理解JS浅拷贝和深拷贝

前端

什么是浅拷贝和深拷贝?

浅拷贝 :只拷贝对象的一层,也就是只拷贝对象的属性值,而不会拷贝对象的属性所指向的对象。

深拷贝 :不仅拷贝对象的一层,还会拷贝对象的属性所指向的对象,以及对象的属性所指向的对象的属性,以此类推,直到拷贝完对象的所有属性及其所指向的对象。

浅拷贝和深拷贝的区别

浅拷贝:

  • 不会拷贝对象的所有属性,只会拷贝对象的属性值。
  • 如果对象的属性是一个引用类型,则浅拷贝只会拷贝该引用,而不会拷贝该引用所指向的对象。
  • 浅拷贝不会递归拷贝对象的所有属性。

深拷贝:

  • 会拷贝对象的所有属性,包括对象的属性所指向的对象,以及对象的属性所指向的对象的属性,以此类推,直到拷贝完对象的所有属性及其所指向的对象。
  • 深拷贝会递归拷贝对象的所有属性。

何时使用浅拷贝和深拷贝?

浅拷贝:

  • 当你需要拷贝一个对象,但不需要拷贝该对象的所有属性时,可以使用浅拷贝。
  • 当你需要拷贝一个对象,并且该对象的所有属性都是基本类型时,可以使用浅拷贝。

深拷贝:

  • 当你需要拷贝一个对象,并且该对象的所有属性都是引用类型时,可以使用深拷贝。
  • 当你需要拷贝一个对象,并且该对象的所有属性都是对象时,可以使用深拷贝。

浅拷贝和深拷贝的例子

浅拷贝示例:

const obj1 = {
  name: "张三",
  age: 18,
  address: {
    city: "北京",
    street: "长安街"
  }
};

const obj2 = {...obj1};

console.log(obj2);

输出:

{
  name: "张三",
  age: 18,
  address: {
    city: "北京",
    street: "长安街"
  }
}

在这个例子中,我们使用 {...obj1} 来创建一个 obj2 的浅拷贝。我们可以看到,obj2nameageaddresscitystreet 属性的值都与 obj1 的值相同。但是,obj2address 属性的引用指向的是 obj1address 属性所指向的同一个对象。

深拷贝示例:

const obj1 = {
  name: "张三",
  age: 18,
  address: {
    city: "北京",
    street: "长安街"
  }
};

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

console.log(obj2);

输出:

{
  name: "张三",
  age: 18,
  address: {
    city: "北京",
    street: "长安街"
  }
}

在这个例子中,我们使用 JSON.parse(JSON.stringify(obj1)) 来创建一个 obj2 的深拷贝。我们可以看到,obj2nameageaddresscitystreet 属性的值都与 obj1 的值相同。而且,obj2address 属性的引用指向的是一个新的对象,而不是 obj1address 属性所指向的同一个对象。

总结

浅拷贝和深拷贝是两种不同的拷贝方式,它们的区别在于浅拷贝只拷贝对象的一层,而深拷贝会拷贝对象的所有属性,包括对象的属性所指向的对象,以及对象的属性所指向的对象的属性,以此类推,直到拷贝完对象的所有属性及其所指向的对象。

浅拷贝和深拷贝的应用场景也有所不同,浅拷贝通常用于拷贝基本类型属性的对象,而深拷贝通常用于拷贝引用类型属性的对象。