垃圾收集如何在JavaScript中工作?

垃圾收集如何在JavaScript中工作? 与.NET垃圾收集类似吗? 这是因为在VBScript中垃圾收集的实现是不好的,人们避免了它,并build立了JavaScript作为他们的标准客户端语言的偏好?

垃圾收集如何工作?

简短的回答是:当一块内存(一个对象,比如说)不再可达时,它有资格被回收。 何时,如何或是否被回收完全取决于实施,不同的实施方式是不同的。 但在语言层面上,这是自动的。

例如:

function foo() { var bar; bar = new ReallyMassiveObject(); bar.someCall(); } 

foo返回时,对象bar指向自动可用于垃圾回收,因为没有任何内容可以引用它。

对比:

 function foo() { var bar; bar = new ReallyMassiveObject(); bar.someCall(); return bar; } // elsewhere var b = foo(); 

…现在对对象的引用仍然存在,直到/除非调用者给bb指定了其他的内容。

与之相反的是:

 function foo() { var bar; bar = new ReallyMassiveObject(); bar.someCall(); setTimeout(function() { alert("Three seconds have passed"); }, 3000); } 

在这里,即使在foo返回之后,定时器机制也具有对定时器callback的引用,并且定时器callback( 闭包 )具有对创build它的上下文的引用,该引用又包含barvariables。 因此,从理论上讲,当foo返回时, bar所指的是什么不能立即用于垃圾收集。 相反,它会一直保持,直到定时器触发并释放对callback的引用,使callback以及引用的符合GC的上下文。 (实际上,现代JavaScript引擎可以并且可以优化闭包,例如,在上面的例子中,静态分析显示callback并不涉及bar ,并且不包含任何evalnew Function代码,可能涉及到它在运行时是dynamic的,所以JavaScript引擎可以安全的离开函数引用的上下文,从而使得它引用的符合GC的条件 – 现代的)。 (更多关于这篇文章中closures。)

JavaScript没有问题处理清理循环引用,顺便说一句,例如:

 function foo() { var a, b; a = {}; b = {}; b.refa = a; a.refb = b; } 

foo返回时, a指的是b ,反之亦然并不是问题。 既然没有别的东西指向他们中的任何一个,他们都可以清理干净。 在IE上,如果其中一个对象是主机提供的对象(如DOM元素或通过new ActiveXObject创build的东西)而不是JavaScript对象,则这不是真的。 (例如,如果你把一个JavaScript对象引用放在一个DOM元素上,并且JavaScript对象引用DOM元素,那么即使没有人引用其中的任何一个,它们也会互相保留)。但这是IE 错误的 问题 ,而不是JavaScript的东西。

回覆:

是不是因为vbscript GC不好,人们回到了JavaScript作为他们的标准客户端API?

JavaScript是原始的客户端网页脚本语言。 VBScript只是后来才出现的,当时微软推出了浏览器,并且只在微软的浏览器中被支持。 如果你想使用最广泛的浏览器,那么JavaScript就是并且是城里唯一的客户端脚本游戏。 这也是VBScript语言的八倍之多。 😉 </主观>

垃圾收集原则上在所有语言中使用类似的方法。 然而,他们的实现在不同的环境中是不同的(例如,每个浏览器使用不同的方式来实现JavaScript GC)。 有关Chrome浏览器GC的简要概述,请参阅此例 。

至于VBScript,它被创build为只能在IE中运行的JavaScript对手/replace语言。 在VBS推出的时候,这是一个相当合理的决定 – IE浏览器共享了90%以上的浏览器份额,而且看起来VBS可以取代当时被广泛支持的,function较差的JavaScript; 不是现在这么多 而且,VBScript基本上是Visual Basic Lite,所有负面的内涵都与该品牌相关。