对象深拷贝的两种实现方式(深度优先,广度优先)

话不多说,直接上代码

<!--工具函数-->
const _toString = Object.prototype.toString
function getType(obj) {
  return _toString.call(obj).slice(8, -1)
}

<!--深度优先-->
function DFSDeepClone(obj, vistied = new Set(), level = 0) {
  let res = {}

  if (getType(obj) === 'Object' || getType(obj) === 'Array') {
    if (vistied.has(obj)) {
      // 处理环状结构
      res = obj
    } else {
      vistied[level] = obj
      vistied.add(obj)
      res = getType(obj) === 'Object' ? {} : []
      Object.keys(obj).forEach(k => {
        res[k] = DFSDeepClone(obj[k], vistied, level + 1)
      })
    }
  } else if (typeof obj === 'function') {
    res = eval(`(${obj.toString()})`)
  } else {
    res = obj
  }

  return res
}

<!--广度优先-->
function BFSDeepClone(obj) {
  if (getType(obj) !== 'Object' && getType(obj) !== 'Array') {
    if (typeof obj === 'function') {
      obj = eval(`(${obj.toString()})`)
    }
    return obj
  }

  let res = {}
  const origin = [obj]
  const copy = [res]
  const vistied = new Set([obj])

  while (origin.length) {
    const _obj = origin.shift()
    const copyObj = copy.shift()

    Object.keys(_obj).forEach(k => {
      const item = _obj[k]
      if (getType(item) === 'Object' || getType(item) === 'Array') {
        if (vistied.has(item)) {
          copyObj[k] = item
        } else {
          vistied.add(item)
          copyObj[k] = getType(item) === 'Object' ? {} : []
          origin.push(item)
          copy.push(copyObj[k])
        }
      } else if (typeof item === 'function') {
        copyObj[k] = eval(`(${item.toString()})`)
      } else {
        copyObj[k] = item
      }
    })
  }

  return res
}
复制代码

缺陷: 没有实现对Symbol属性的处理,如果想实现的话可以用 Object.getOwnPropertySymbols()得到所有的Symbol属性,然后去遍历。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值