Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
haizhilin2013 opened this issue Oct 26, 2020 · 3 comments
Open

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

haizhilin2013 opened this issue Oct 26, 2020 · 3 comments
Labels
js JavaScript

Comments

@haizhilin2013
Copy link
Collaborator

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

作者:Alex

3+1官网

我也要出题

@haizhilin2013 haizhilin2013 added the js JavaScript label Oct 26, 2020
@qubitsky
Copy link

qubitsky commented Oct 27, 2020

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

@bitQ2019
Copy link

learned

@maoxiaoxing
Copy link

发一个简易版的吧,不能拷贝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
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
js JavaScript
Projects
None yet
Development

No branches or pull requests

4 participants