Javascript/ECMAScript垃圾收集

K2x*_*2xL 3 javascript garbage-collection settimeout

请考虑以下代码(您可以将它放在Chrome中的开发人员控制台中并检查).

var obj = {
    f: function () {
        var myRef = this;
        val = setTimeout(function () { 
            console.log("time down!"); 
            myRef.f();
        }, 1000);
    }
};
Run Code Online (Sandbox Code Playgroud)

如果我然后跑

obj.f();
Run Code Online (Sandbox Code Playgroud)

启动计时器,我可以看到每一秒"时间下降!"

如果我然后跑

obj = null;
Run Code Online (Sandbox Code Playgroud)

计时器仍然会闪光.

只是好奇为什么不垃圾收集清除计时器?可怕的是,现在似乎没有办法删除计时器 - 我是否正确?

我的猜测是技术上window仍然保持对对象的引用,因此对象保留在内存中.我在另一个基于ECMA的语言(Actionscript)中遇到过这个问题并构建了一个用于处理它的库,但有点想法Javascript会采用不同的方法.

Dom*_*nic 7

obj不是垃圾收集,因为您传递给的闭包setTimeout必须保持在周围才能执行.反过来,它持有一个参考,obj因为它捕获myRef.

如果将该闭包传递给任何其他保持它的函数(例如在数组中),它将是相同的.

现在没有办法删除计时器,没有可怕的黑客1.但这很自然:它是一个对象的工作,清理自己.该对象的目的是无限地触发超时,因此该对象显然打算永远不会在自身之后进行清理,这可能是合适的.你不能指望在没有使用至少一些内存的情况下永远发生某些事情.


1可怕的黑客攻击:由于计时器ID只是整数,你可以从1到1000000000循环并调用clearTimeout每个整数.显然这会杀死其他正在运行的计时器!