[js] 第560天 深拷贝里的循环引用如何解决?
Opened this issue · 3 comments
haizhilin2013 commented
qubitsky commented
考察的是如何实现深拷贝问题。深拷贝需要为每一个对象属性创建新的对象,但是如果单纯这样做碰到含有循环引用的对象,就会进入死循环。
这么操作当然是错误的,为了正确进行深拷贝,不出现这种错误,就需要:
遍历原对象每个节点的时候,记录该节点是否被访问过,这样当在遍历过程中再次访问到该节点,说明该节点已经创建过,此时不需要新创建对象,而是指向已创建的对象
bitQ2019 commented
learned
maoxiaoxing commented
发一个简易版的吧,不能拷贝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
}