Jus*_*rce 8 javascript garbage-collection scope anonymous-function
我的直觉是,在这样的匿名函数中封装代码块是个好主意:
(function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
})();
Run Code Online (Sandbox Code Playgroud)
因为我不再需要aVar了,所以我假设垃圾收集器会aVar在超出范围时删除.这是正确的吗?或者是口译员足够聪明,看到我不再使用变量并立即清理它?是否有任何理由,如风格或可读性,我应该不使用匿名函数这种方式?
另外,如果我命名函数,如下所示:
var operations = function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
};
operations();
Run Code Online (Sandbox Code Playgroud)
不operations那么必然留下来,直到它超出范围?或者口译员可以立即告诉它何时不再需要?
我还想澄清一点,我不一定谈论全球范围.考虑一个看起来像的块
(function() {
var date = new Date(); // I want to keep this around indefinitely
// And even thought date is private, it will be accessible via this HTML node
// to other scripts.
document.getElementById('someNode').date = date;
// This function is private
function someFunction() {
var someFuncMember;
}
// I can still call this because I named it. someFunction remains available.
// It has a someFuncMember that is instantiated whenever someFunction is
// called, but then goes out of scope and is deleted.
someFunction();
// This function is anonymous, and its members should go out of scope and be
// deleted
(function() {
var member;
})(); // member is immediately deleted
// ...and the function is also deleted, right? Because I never assigned it to a
// variable. So for performance, this is preferrable to the someFunction
// example as long as I don't need to call the code again.
})();
Run Code Online (Sandbox Code Playgroud)
我的假设和结论是否正确?每当我不打算重复使用的模块,我不应该只将其封装在一个功能,但在一个匿名函数封装它,这样的函数没有引用,这就是所谓后删除了,对不对?
你是对的,将变量粘贴在匿名函数中是避免弄乱全局对象的好习惯。
\n\n回答后两个问题:解释器完全不可能知道只要存在对某个对象的全局可见引用,该对象就不会被再次使用。据解释器所知,您可以随时评估一些依赖于window[\'aVar\']或 的代码。window[\'operation\']
本质上,记住两件事:
\n\nwindow在客户端 Javascript 中)。总而言之,这些意味着全局变量中的对象在脚本的生命周期内持续存在(除非重新分配变量)。这就是为什么我们声明匿名函数 \xe2\x80\x94 变量获得一个新的上下文对象,该对象在函数完成执行后立即消失。除了提高效率之外,它还减少了名称冲突的机会。
\n\n不过,您的第二个示例(使用内部匿名函数)可能有点过于热心。我不担心“帮助垃圾收集器”,\xe2\x80\x94 GC 可能不会在该函数中间运行。担心那些会持续保留的东西,而不仅仅是比原本保留的时间稍长一些。这些自动执行的匿名函数基本上是自然归属在一起的代码模块,因此一个好的指南是考虑这是否描述了您正在做的事情。
\n\n不过,在匿名函数中使用匿名函数是有原因的。例如,在这种情况下:
\n\n(function () {\n var bfa = new Array(24 * 1024*1024);\n var calculation = calculationFor(bfa);\n $(\'.resultShowButton\').click( function () {\n var text = "Result is " + eval(calculation);\n alert(text);\n } );\n})();\nRun Code Online (Sandbox Code Playgroud)\n\n这会导致点击回调捕获该巨大的数组,使其永远不会消失。您可以通过在其自己的函数内隔离数组来避免这种情况。
\n