JS垃圾回收机制中的引用计数

window.onload = function(){

    var el = document.getElementById("id");

    el.onclick = function(){

        alert(el.id);

    }

}

window.onload=function outerFunction(){

    var obj = document.getElementById("element");

    obj.onclick=function innerFunction(){};

}

这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中的变量,自然也包括obj,请问怎么理解这个两个循环引用?


繁花如伊
浏览 900回答 2
2回答

白衣染霜花

这个其实涉及到作用域和闭包的概念,el.onclick和obj.onclick的方法内部其实是一个新的作用域,然后方法实际上是一个outerFunction外部的函数,因为DOM监听事件不可能是局部作用域的,是全局作用域的,这就构成了一个闭包的条件,能够通过外部调用访问函数内部的私有变量,也就是能够访问outerFunction中的变量,因此间接的引用了outerFunction的活动变量中的el,obj变量,除此之外el,obj中的属性onclick指向了匿名函数所在的内存区,这样导致了互相引用循环引用

守着星空守着你

自己用V8测试了一下,垃圾回收的时候外部环境的作用域并不会全部保留,只会留下函数引用的变量,估计是做了变量分析优化。obj.onclick=function innerFunction(){},innerFunction函数并没有引用什么。循环引用类似  var o = {};  var o2 = {};   o.a = o2; // o 引用 o2   o2.a = o; // o2 引用 o在使用计数清除法的时候这个变量就永远不会清除掉。以前大多是直接给变量赋值null的方式来清除。从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。这个算法把“对象是否不再需要”简化定义为“对象是否可以获得”。这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。定期的,垃圾回收器将从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和所有不能获得的对象。内存管理看《Node深入浅出》垃圾回收笔记:
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript