Pau*_*ite 31 javascript memory
在过去的某个时刻,我读到了一些让我觉得JavaScript中的匿名函数可以消耗大量内存的想法(因为它们带有整个当前范围),而命名(静态?)函数不是'有这个问题.
我不记得我在哪里读到这个,所以我不能回去重新阅读它并为自己弄清楚这一点.
我有两个问题:
所有JavaScript函数的行为方式都相同,因为它们继承了整个作用域链中的变量环境,直到并包括它们自身.对于匿名和命名函数同样如此.
即使函数被传递到完全不同的范围,这个对外部环境的引用链仍然保留在每个函数中.
传统上,这意味着只要内部闭包继续存在,任何给定链中的所有变量都会保留一个引用.虽然在编译代码的现代浏览器中,可能会分析哪些变量实际被引用,并且只保留那些变量,允许不再引用的其他变量被垃圾收集.
但是,还有其他情况下匿名函数是浪费的.
这是一个常见的代码:
for( var i = 0; i < 100; i++ ) {
(function( j ) {
setTimeout( function() { console.log( j ); }, 1000 );
})( i );
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,匿名函数比命名函数更浪费,因为您在循环期间重新创建相同的函数100次,而您可以重用已命名的函数.
function setConsole( j ) {
setTimeout( function() { console.log( j ); }, 1000 );
}
for( var i = 0; i < 100; i++ ) {
setConsole( i );
}
Run Code Online (Sandbox Code Playgroud)
这具有完全相同的闭包开销,但更有效,因为您只构造了一个函数来创建每个新的变量环境.
http://jsperf.com/immediate-vs-named (感谢@Felix Kling为jsPerf.)
因此,特别是对于闭包,只要您通过一些永久性引用来保持闭包,就会有开销.我会说如果可能的话,尽量避免这种情况是好的,但不要过于强迫它.有时,添加到范围链中的新变量环境只是最佳解决方案.
编辑: 这是谷歌的一篇文章.具体来说,请参阅避免闭包陷阱.有关扩展范围链的性能影响的信息,以及匿名函数比命名函数"更慢"的声明.