返回

JS 深拷贝与浅拷贝知识全攻略

前端

目录

  1. 什么是深拷贝和浅拷贝?
  2. 深拷贝与浅拷贝的区别
  3. 浅拷贝的实现方式
  4. 深拷贝的实现方式
    • 手动深拷贝
    • JSON 深拷贝
    • Lodash 深拷贝
  5. 何时使用深拷贝,何时使用浅拷贝
  6. 总结

正文

1. 什么是深拷贝和浅拷贝?

在JavaScript中,变量可以存储两种类型的数据:基本类型和引用类型。基本类型包括数字、字符串和布尔值,而引用类型包括对象和数组。

  • 浅拷贝 :浅拷贝只复制一层对象的属性,即只复制对象的直接属性,而不复制对象的嵌套属性。
  • 深拷贝 :深拷贝会复制对象的所有属性,包括对象的嵌套属性。

2. 深拷贝与浅拷贝的区别

下表列出了深拷贝与浅拷贝的区别:

特征 浅拷贝 深拷贝
复制层次 只复制一层属性 复制所有属性
复制方式 按引用复制 按值复制
结果 两个对象指向同一块内存地址 两个对象指向不同的内存地址

3. 浅拷贝的实现方式

浅拷贝可以通过使用对象的赋值运算符(=)来实现。例如:

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

const obj2 = obj1;

在上面的代码中,obj2被赋值为obj1的引用。这意味着obj2和obj1指向同一块内存地址。因此,对obj2的任何更改都会反映在obj1上,反之亦然。

4. 深拷贝的实现方式

深拷贝可以通过多种方式来实现,包括手动深拷贝、JSON 深拷贝和 Lodash 深拷贝。

4.1 手动深拷贝

手动深拷贝可以通过递归的方式来实现。递归是一种函数调用自身的编程技术。在手动深拷贝中,我们可以使用递归来复制对象的所有属性,包括对象的嵌套属性。

例如,我们可以使用以下代码来实现手动深拷贝:

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

  const newObj = Array.isArray(obj) ? [] : {};

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

  return newObj;
}

在上面的代码中,deepCopy()函数首先检查obj是否是一个对象或数组。如果不是,则直接返回obj。

如果是对象或数组,则创建一个新的对象或数组newObj。然后,使用for...in循环遍历obj的所有属性。对于每个属性,使用deepCopy()函数递归复制该属性的值。

最后,返回newObj。

4.2 JSON 深拷贝

JSON 深拷贝可以通过使用JSON.parse()和JSON.stringify()方法来实现。JSON.parse()方法可以将JSON字符串解析为JavaScript对象,而JSON.stringify()方法可以将JavaScript对象转换为JSON字符串。

例如,我们可以使用以下代码来实现JSON 深拷贝:

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

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

在上面的代码中,首先使用JSON.stringify()方法将obj1转换为JSON字符串。然后,使用JSON.parse()方法将JSON字符串解析为JavaScript对象obj2。

这样,obj2就成为了obj1的深拷贝。

4.3 Lodash 深拷贝

Lodash是一个流行的JavaScript库,提供了许多有用的函数,其中包括一个深拷贝函数。我们可以使用以下代码来实现Lodash 深拷贝:

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

const obj2 = _.cloneDeep(obj1);

在上面的代码中,我们使用_.cloneDeep()函数来复制obj1。这样,obj2就成为了obj1的深拷贝。

5. 何时使用深拷贝,何时使用浅拷贝

浅拷贝和深拷贝都有其各自的用途。一般来说,当我们只需要复制对象的直接属性时,就可以使用浅拷贝。而当我们需要复制对象的嵌套属性时,就需要使用深拷贝。

例如,如果我们有一个对象,其中包含一个数组属性,并且该数组属性包含另一个对象,那么我们需要使用深拷贝来复制该对象,才能确保复制出该对象的所有属性,包括数组属性和数组属性中的对象。

6. 总结

深拷贝与浅拷贝是JavaScript中两种重要的复制技术。深拷贝可以复制对象的所有属性,包括对象的嵌套属性,而浅拷贝只复制一层对象的属性。

在实际应用中,我们可以根据需要选择使用深拷贝或浅拷贝。一般来说,当我们只需要复制对象的直接属性时,就可以使用浅拷贝。而当我们需要复制对象的嵌套属性时,就需要使用深拷贝。