美文网首页
js深拷贝广度优先及深度优先处理Symbol

js深拷贝广度优先及深度优先处理Symbol

作者: 李仁平 | 来源:发表于2021-06-07 14:51 被阅读0次

js对象深拷贝,文章使用了广度优先和深度优先,同时也出来了symbol类型的拷贝。

<!--工具函数-->
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' ? {} : [];
      Reflect.ownKeys(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()

     Reflect.ownKeys(_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
}

文章转载优化来源:

相关文章

网友评论

      本文标题:js深拷贝广度优先及深度优先处理Symbol

      本文链接:https://www.haomeiwen.com/subject/skkosltx.html