返回

10种技巧帮助你深拷贝JavaScript对象

前端

什么是深拷贝?

在JavaScript中,对象是一种复杂的数据类型,它可以包含多个属性和值。当我们需要将一个对象赋值给另一个对象时,通常情况下会使用赋值运算符(=)。但是,这种赋值操作仅仅是将对象的引用赋值给了另一个对象,而不是将对象的值复制给另一个对象。这意味着,如果我们对其中一个对象的值进行了修改,另一个对象的值也会受到影响。

为了避免这种情况,我们需要使用深拷贝来复制对象。深拷贝是指将一个对象的所有属性和值完整地复制到另一个新对象中。这样,无论我们对其中一个对象的值进行了修改,另一个对象的值都不会受到影响。

如何实现深拷贝?

1. 迭代递归法

这是最常规的方法,思路很简单,就是利用递归将对象中的每个属性和值都复制到一个新对象中。需要注意的是,在复制对象属性时,如果该属性也是一个对象,那么我们需要再次调用递归函数来复制该对象。

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) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopy(obj[key]);
    }
  }

  return newObj;
}

2. JSON.parse()和JSON.stringify()

利用JSON.stringify()将对象转换为JSON字符串,然后再利用JSON.parse()将JSON字符串转换为对象。

function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj));
}

3. Object.assign()

Object.assign()方法可以将一个或多个对象的属性复制到目标对象。

function deepCopy(obj) {
  return Object.assign({}, obj);
}

4. 扩展运算符(...)

扩展运算符(...)可以将一个对象展开为一系列的属性和值,然后再利用Object.assign()方法将这些属性和值复制到目标对象。

function deepCopy(obj) {
  return {...obj};
}

5. 正则表达式

利用正则表达式来将对象转换为JSON字符串,然后再利用JSON.parse()方法将JSON字符串转换为对象。

function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj).replace(/\b(?=(\d+)):/g, '"$1":'));
}

6. 结构化克隆算法

结构化克隆算法是一种用于复制对象的值的算法。它可以复制对象的所有属性和值,包括不可枚举的属性和值。

function deepCopy(obj) {
  return structuredClone(obj);
}

7. 第三方库

我们可以使用第三方库来实现深拷贝,例如Lodash和jQuery。

// 使用Lodash
function deepCopy(obj) {
  return _.cloneDeep(obj);
}

// 使用jQuery
function deepCopy(obj) {
  return $.extend(true, {}, obj);
}

8. ES6的新特性

ES6中引入了一些新的特性,可以帮助我们实现深拷贝。例如,我们可以使用Proxy对象来创建一个新的对象,该对象可以代理另一个对象的行为。当我们访问代理对象时,实际上是访问了被代理的对象。这样,我们可以通过代理对象来实现深拷贝。

function deepCopy(obj) {
  return new Proxy({}, {
    get: function(target, property) {
      return deepCopy(obj[property]);
    }
  });
}

总结

以上是实现深拷贝JavaScript对象的方法,这些方法各有优缺点,我们可以根据自己的需要选择合适的方法。