返回

JavaScript深拷贝与浅拷贝,从理解赋值开始每天进步一点点!

前端

浅析JavaScript中的赋值

在JavaScript中,赋值是一个非常基本的操作,它可以将一个变量的值复制给另一个变量。赋值操作的语法很简单,只需使用等号(=)即可。例如,以下代码将变量a的值复制给变量b:

let a = 10;
let b = a;

现在,变量b的值也变成了10。需要注意的是,JavaScript中的赋值是浅拷贝,这意味着它只复制变量的值,而不会复制变量引用的对象。例如,以下代码将变量a的值复制给变量b:

let a = { name: 'John Doe' };
let b = a;

现在,变量b的值也变成了一个对象,该对象具有name属性,其值为'John Doe'。但是,变量b实际上并没有复制变量a引用的对象,而是创建了一个新的对象。这意味着,如果我们更改变量a引用的对象的属性值,变量b引用的对象属性值不会受到影响。例如,以下代码将变量a引用的对象的name属性值更改为'Jane Doe':

a.name = 'Jane Doe';

现在,变量a引用的对象的name属性值为'Jane Doe',但变量b引用的对象的name属性值仍然为'John Doe'。

深拷贝与浅拷贝的异同

浅拷贝只复制变量的值,而深拷贝则复制变量值及其引用的所有对象。例如,以下代码将变量a引用的对象进行深拷贝,并将其存储在变量b中:

let a = { name: 'John Doe' };
let b = JSON.parse(JSON.stringify(a));

现在,变量b的值也是一个对象,该对象具有name属性,其值为'John Doe'。但是,与浅拷贝不同,变量b实际上复制了变量a引用的对象,这意味着,如果我们更改变量a引用的对象的属性值,变量b引用的对象属性值也会受到影响。例如,以下代码将变量a引用的对象的name属性值更改为'Jane Doe':

a.name = 'Jane Doe';

现在,变量a引用的对象的name属性值为'Jane Doe',变量b引用的对象的name属性值也变成了'Jane Doe'。

何种情况下需要使用深拷贝

在某些情况下,我们需要使用深拷贝来确保变量引用的对象不会受到意外更改的影响。例如,在以下场景中,我们应该使用深拷贝:

  • 当我们将变量传递给一个函数时,并且该函数可能会更改变量引用的对象。
  • 当我们将变量存储在一个全局变量中时,并且该变量可能会被多个函数访问。
  • 当我们将变量存储在一个本地存储或Cookie中时,并且该变量可能会被其他网站访问。

如何实现深拷贝

JavaScript中有多种方法可以实现深拷贝,最常见的方法是使用JSON.parse()和JSON.stringify()函数。以下代码演示了如何使用JSON.parse()和JSON.stringify()函数实现深拷贝:

let a = { name: 'John Doe' };
let b = JSON.parse(JSON.stringify(a));

现在,变量b的值也是一个对象,该对象具有name属性,其值为'John Doe'。但是,变量b实际上复制了变量a引用的对象,这意味着,如果我们更改变量a引用的对象的属性值,变量b引用的对象属性值也会受到影响。

另一种实现深拷贝的方法是使用递归函数。以下代码演示了如何使用递归函数实现深拷贝:

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

  if (obj instanceof Array) {
    return obj.map(deepCopy);
  }

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

  return newObj;
}

现在,我们可以使用deepCopy()函数来实现深拷贝:

let a = { name: 'John Doe' };
let b = deepCopy(a);

现在,变量b的值也是一个对象,该对象具有name属性,其值为'John Doe'。但是,变量b实际上复制了变量a引用的对象,这意味着,如果我们更改变量a引用的对象的属性值,变量b引用的对象属性值也会受到影响。

总结

在JavaScript中,赋值是浅拷贝,这意味着它只复制变量的值,而不会复制变量引用的对象。深拷贝则复制变量值及其引用的所有对象。在某些情况下,我们需要使用深拷贝来确保变量引用的对象不会受到意外更改的影响。JavaScript中有多种方法可以实现深拷贝,最常见的方法是使用JSON.parse()和JSON.stringify()函数或递归函数。