Skip to content

深拷贝

引用类型的深拷贝方法,可解决深层嵌套、循环引用问题

点击查看代码
js
function deepClone(target) {
  // 记录所有对象的引用
  const map = new WeakMap()

  function isObject(source) {
    if (!source || typeof source !== 'object') {
      return false
    } else {
      return true
    }
  }

  function clone(target) {
    if (!isObject(target)) return

    let result = null
    // 检查循环引用,存在引用过的则直接返回
    const referenced = map.get(target)
    if (referenced) {
      return referenced
    }
    // 区分数据类型
    result = Array.isArray(target) ? [] : {}
    // 记录当前引用值,result为引用地址,值会被后续操作改变
    map.set(target, result)

    Object.keys(target).forEach(key => {
      if (isObject(target[key])) {
        result[key] = clone(target[key])
      } else {
        result[key] = target[key]
      }
    })

    return result
  }

  return clone(target)
}

测试

js
/* 深层嵌套 */
let obj = { name: 'xxx', arr: [1, 2, 3], sec: { content: { age: 18 } }, fn: () => {} }
let cloneObj = deepClone(obj)
obj.sec.content.age = 22
obj.arr.push(4)
console.log(obj, 'obj')
console.log(cloneObj, 'cloneObj')

/* 循环引用 */
let a = { name: 'aa', arr: [3, 4] }
let b = { name: 'bb' }
a.child = b
b.parent = a
console.log(a, 'source')
let cloneA = deepClone(a)
console.log(cloneA, 'clone')

查看代码

Updated at: