一天两个JS手写题之---手动实现JS深拷贝

164 阅读2分钟

深拷贝是指将一个对象完整复制一份,并且与原对象完全隔离,这样对于拷贝后的对象的修改不会影响原对象,通常用于复制对象以便在不同的上下文中使用。

在 JavaScript 中,常常使用浅拷贝,即只复制对象的引用,而不是复制整个对象。这意味着如果修改了拷贝后的对象,原对象也会受到影响。因此,在某些情况下,我们需要实现深拷贝。

下面是使用 JavaScript 手写实现一个深拷贝函数:

function deepClone(obj) {
  if (typeof obj !== 'object' || obj === null) {
    // 如果不是复杂数据类型,直接返回
    return obj;
  }

  let copy = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepClone(obj[key]);
    }
  }

  return copy;
}

这个函数的实现过程比较简单,主要步骤如下:

  1. 检查传入的参数是否为复杂数据类型,如果不是,直接返回该值。
  2. 创建一个新对象或数组,用于存储深拷贝后的值。
  3. 遍历原对象或数组中的属性,递归地调用 deepClone 函数,并将属性的值赋值给新对象或数组。
  4. 返回新对象或数组。

该函数实现了对对象、数组以及嵌套的对象和数组进行深拷贝。但是,该函数存在以下问题:

  1. 无法处理循环引用。如果在深拷贝的对象中存在循环引用,则函数将陷入死循环并最终导致堆栈溢出。
  2. 无法处理一些特殊的对象,比如函数、正则表达式等。

因此,在实际应用中,需要根据具体情况对该函数进行优化或选择其他更好的解决方案。

在实现深拷贝时,还需要考虑性能问题。如果对象或数组非常大,或者嵌套层数很深,使用递归函数会导致性能问题。因此,可以使用迭代的方式实现深拷贝,这样可以减少递归调用的次数。

另外,ES6 提供了 Object.assign() 方法可以用来实现浅拷贝。该方法接受一个目标对象和一个或多个源对象,将源对象的属性复制到目标对象中,返回目标对象。如果要实现深拷贝,可以结合使用 Object.assign() 和递归函数来实现。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情