返回

剖析JS深拷贝与浅拷贝的异同,掌握一招巧妙实现深拷贝(基础指南)

前端

前言:浅尝辄止与深谋远虑
在JavaScript的王国里,数据复制是开发人员经常需要面对的挑战。数据复制有多种方式,其中浅拷贝和深拷贝是两种最常用的方法。浅拷贝仅复制对象的第一层数据,而深拷贝则复制对象的所有层级数据,包括嵌套对象和数组。

一、浅拷贝:镜花水月,似是而非

浅拷贝,顾名思义,只复制一层数据。当您对一个对象进行浅拷贝时,您将创建一个新对象,该对象具有与原始对象相同的值,但它是原始对象的独立副本。

浅拷贝可以使用以下方法实现:

  • 对象赋值:
let obj1 = {name: 'John Doe', age: 30};
let obj2 = obj1;
  • 扩展运算符:
let obj1 = {name: 'John Doe', age: 30};
let obj2 = {...obj1};

使用上述方法创建的副本对象obj2将包含对原始对象obj1中数据的引用。这意味着对副本对象obj2所做的任何更改都将反映在原始对象obj1中。

二、深拷贝:抽丝剥茧,尽收眼底

深拷贝,则更加彻底,它会复制对象的所有层级数据,包括嵌套对象和数组。当您对一个对象进行深拷贝时,您将创建一个新对象,该对象具有与原始对象相同的值,但它与原始对象完全独立,对新对象的任何更改都不会影响原始对象。

深拷贝可以使用以下方法实现:

  • 递归:
    这是一个经典的深拷贝实现方法,使用递归来遍历对象的所有层级,并创建新对象的副本。
function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(item => deepCopy(item));
  }

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

  return newObj;
}
  • JSON.parse()和JSON.stringify():
    这是一种更简单的方法来实现深拷贝。首先使用JSON.stringify()将对象转换为JSON字符串,然后使用JSON.parse()将JSON字符串解析回对象。
function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj));
}

使用上述方法创建的副本对象obj2将完全独立于原始对象obj1,对副本对象obj2所做的任何更改都不会影响原始对象obj1。

三、何时使用深拷贝,何时使用浅拷贝?

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

  • 浅拷贝: 通常适用于以下场景:

    • 当您需要创建对象的副本,但并不需要修改副本对象中的数据时。
    • 当您需要在多个地方使用相同的数据时。
    • 当您需要节省内存时。
  • 深拷贝: 通常适用于以下场景:

    • 当您需要创建对象的副本,并且需要修改副本对象中的数据时。
    • 当您需要将对象传递给另一个函数或库,并且您不想让该函数或库修改原始对象时。
    • 当您需要在多个线程或进程中使用相同的数据时。

四、结语:深谙浅拷贝与深拷贝,游刃有余应万变

浅拷贝和深拷贝是JavaScript中两种重要的数据复制方法,掌握它们的区别和应用场景,可以帮助您在日常开发中游刃有余,轻松应对各种数据复制的需求。