对象循环引用

1.父级引用

这里的父级引用指的是,当对象的某个属性,正是这个对象本身,此时我们如果进行深拷贝,可能会在子元素->父对象->子元素...这个循环中一直进行,导致栈溢出。

解决办法是:只需要判断一个对象的字段是否引用了这个对象或这个对象的任意父级即可,可以修改上面的deepCopy函数:

2. 同级引用

假设对象obj有a,b,c三个子对象,其中子对象c中有个属性d引用了对象obj下面的子对象a。

解决方案:父级的引用是一种引用,非父级的引用也是一种引用,那么只要记录下对象A中的所有对象,并与新创建的对象一一对应即可。

深拷贝如何解决对象循环引用?

WeakMap

DOM元素与一个原生JS对象之间创建循环引用

window.οnlοad = function outerFunction() {
    var obj = document.getElementById("element"):
        obj.οnclick = function innerFunction() {};
};

这段代码看起来没什么问题,但是 obj 引用了 document.getElementById(“element”),而 document.getElementById(“element”)的 onclick 方法会引用外部环境中的变量,自然也包括 obj,是不是很隐蔽啊。

最简单的解决方式就是自己手工解除循环引用,比如刚才的函数可以这样

myObject.element = null;
element.o = null;
window.οnlοad = function outerFunction() {
    var obj = document.getElementById("element"):
        obj.οnclick = function innerFunction() {};
    obj = null;
};

将变量设置为 null 意味着切断变量与它此前引用的值之间的连接。当垃圾回收器下次运行时,就会删除这些值并回收它们占用的内存。 要注意的是,IE9+并不存在循环引用导致 Dom 内存泄漏问题,可能是微软做了优化,或者 Dom 的回收方式已经改变

来源整理自:vue3js.cn 面试官系列