前言

在 JavaScript 中,深拷贝(深度克隆)是指创建一个新的对象或数组,并将原始对象或数组的所有属性或元素复制到新对象或数组中。这样做的好处是,新对象或数组是独立的,对它的修改不会影响原始对象或数组


正统递归

优点

  1. 灵活性:递归算法可以适用于各种对象类型和数据结构,包括复杂的嵌套对象和数组。
  2. 控制精度:通过手动编写递归深拷贝算法,您可以精确控制每个属性或元素的复制方式,以满足特定需求。
  3. 不依赖第三方库:递归深拷贝是一种自主实现的方法,不需要依赖任何第三方库或工具。

缺点:

  1. 复杂性:递归深拷贝的实现可能相对复杂,特别是当处理复杂的对象结构、循环引用或特殊类型(如日期对象)时。
  2. 性能开销:递归深拷贝可能会导致较大的性能开销,特别是在处理大型对象或嵌套层次很深的对象时。每次递归调用都会带来一定的开销。
  3. 潜在的无限递归:如果递归深拷贝算法没有正确处理循环引用的情况,可能会导致无限递归,最终导致堆栈溢出或死循环

示例:

function deepCopy(obj, visited = new WeakMap()) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }
  
  if (visited.has(obj)) {
    return visited.get(obj);
  }
  
  let copy;
  
  if (Array.isArray(obj)) {
    copy = [];
    visited.set(obj, copy);
    for (let i = 0; i < obj.length; i++) {
      copy[i] = deepCopy(obj[i], visited);
    }
  } else {
    copy = {};
    visited.set(obj, copy);
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        copy[key] = deepCopy(obj[key], visited);
      }
    }
  }
  
  return copy;
}

测试:包含了对象、数组、函数、递归引用

let originalObj = { foo: 'bar', baz: [1, 2, 3], f: function() {} };
originalObj.h = originalObj;
let newObj = deepCopy(originalObj);

JSON处理

优点:

  1. 简单易用:JSON 处理是一种通用的方法,可以轻松地实现深拷贝。通过将对象转换为 JSON
    字符串,然后将其解析为新的对象,可以实现对象的完整复制。
  2. 支持多种对象类型:JSON 处理可以处理包括对象、数组、字符串、数字、布尔值和 null 在内的多种对象类型。
  3. 无需手动编写复制逻辑:与手动递归复制相比,使用 JSON 处理可以避免编写复制逻辑,减少了出错的可能性。

缺点:

  1. 无法处理特殊对象类型:JSON无法处理一些特殊的对象类型,例如函数、循环引用和特定的内置对象(如日期对象)等。在处理这些对象类型时,可能需要进行额外的处理或特殊处理。
  2. 丢失对象的原型和方法:通过JSON处理,对象的原型链和方法将丢失。解析后的对象将成为普通的对象,不再具有原始对象的原型和方法。
  3. 性能开销:将对象转换为JSON字符串和解析JSON字符串为对象的过程可能会产生一定的性能开销,特别是在处理大型对象或嵌套层次很深的对象时。

示例:

let originalObj = { foo: 'bar', baz: [1, 2, 3] };
// originalObj.f=function() {}; // 不支持
// originalObj.h=originalObj; // 不支持
let newObj = JSON.parse(JSON.stringify(originalObj));
console.log(newObj);

Last modification:December 7, 2023
如果觉得我的文章对你有用,您可以给博主买一杯果汁,谢谢!