haizlin/fe-interview

[js] 第560天 深拷贝里的循环引用如何解决?

Opened this issue · 3 comments

第560天 深拷贝里的循环引用如何解决?

作者:Alex

3+1官网

我也要出题

考察的是如何实现深拷贝问题。深拷贝需要为每一个对象属性创建新的对象,但是如果单纯这样做碰到含有循环引用的对象,就会进入死循环。
这么操作当然是错误的,为了正确进行深拷贝,不出现这种错误,就需要:
遍历原对象每个节点的时候,记录该节点是否被访问过,这样当在遍历过程中再次访问到该节点,说明该节点已经创建过,此时不需要新创建对象,而是指向已创建的对象

learned

发一个简易版的吧,不能拷贝Map,Set,和其他复杂类型数据,如果想实现的话,可以自己根据类型去判断,然后实现

const deepCopy = function(obj, map = new WeakMap()) {
    if (obj === null) return obj // 如果是null,直接返回
    if (obj instanceof RegExp) return new RegExp(obj) // 判断正则
    if (obj instanceof Date) return new Date(obj) // 判断日期
    if (typeof obj !== 'object') return obj // 判断非引用类型,直接返回

    if (map.has(obj)) return map.get(obj) // 如果已经存在,则直接返回

    const res = new obj.constructor() // 找到当前数据的构造函数,创建对象

    map.set(obj, res) // 将新建对象存起来,防止循环引用
    
    for(const i in obj) {
      res[i] = deepCopy(obj[i], map) // 递归拷贝
    }
    return res
  }