js深拷贝的三种实现方式

1、

JSON.parse(JSON.stringify(obj))

这种深拷贝的方法很简单、简洁。

但是不推荐这种。

因为,如果对象内容项为undefined、null、Date、RegExp、function……深拷贝时会出现问题

2、

使用第三方库,比如lodash的cloneDeep()方法

import lodash from 'lodash';

let obj = {
  a: {
    b: 'xxx'
  }
}

const newObj = lodash.cloneDeep(obj);

3、

使用递归。

使用递归,又分为两种,基础班和兼容数组版。

(1)基础版

const obj = {
  a: {
    b: 'hello'
  },
  c: 123
}

function cloneDeep(target) {
  // 判断是否为对象
  if (typeof target === 'object') {
    let obj = {}
    for(let i in target) {
      obj[i] = cloneDeep(target[i])
    }
    return obj
  } else {
    return target
  }
}

let newObj = cloneDeep(obj)
newObj.c = 666
console.log('newObj', newObj)
console.log('obj', obj)

根据打印的结果,我修改了深拷贝的对象,原对象的值并没有变化,说明深拷贝没问题。

(2)兼容数组版

我们不能只考虑对象而不考虑数组,这是兼容数组版:

const obj = {
  a: {
    b: 'hello'
  },
  c: 123,
  d: [1, 2, 3]
}
function cloneDeep(target) {
  // 判断是否为对象
  if(typeof target === 'object') {
    let obj = Array.isArray(target) ? [] : {}
    for(let i in target) {
      obj[i] = cloneDeep(target[i])
    }
    return obj
  } else {
    return target
  }
}
let newObj = cloneDeep(obj)
newObj.d = [1, 2]
console.log('newObj', newObj)
console.log('obj', obj)

看这个打印结果,深拷贝数组没问题。