JS 深拷贝

151 阅读1分钟

方法一:JSON

const cloneObj = JSON.parse(JSON.stringify(obj))

缺点:

  1. 不支持拷贝undefined、正则、函数、Date
  2. 不支持引用

方法二:手写深拷贝

注意:

  1. 判断类型
  2. 检查环
  3. 递归
  4. 不拷贝原型上的属性
const deepClone = (target, cache) => {
  if (!cache) {
    cache = new Map() // map可以将对象作为key
  }
  let result
  if (target instanceof Object) {
    if (cache.get(target)) {
      return cache.get(target)
    }
    // 深拷贝对象
    if (target instanceof Function) {
      if (target.prototype) {
        // 有prototype就是普通函数
        result = function () {
          return target.apply(this, arguments)
        }
      } else {
        result = (...args) => {
          //箭头函数没有arguments
          return target.apply(undefined, ...args)
        }
      }
    } else if (target instanceof Array) {
      result = []
    } else if (target instanceof Date) {
      result = new Date(target - 0) // target-0 获取时间戳
    } else if (target instanceof RegExp) {
      result = new RegExp(target.source, target.flags)
    } else {
      result = {}
    }
    cache.set(target, result)
    // 属性拷贝
    for (let key in target) {
      if (target.hasOwnProperty(key)) {
        // 递归
        result[key] = deepClone(target[key], cache)
      }
    }
  } else {
    // number string Boolean null undefined symbol bigInt
    result = target
  }
  return result
}