在过去的某个时候,我读到一些东西,它让我想到 JavaScript 中的匿名函数会占用惊人的内存量(因为它们随身携带整个当前作用域) ,而命名(静态?)函数没有这个问题。
我不记得我在哪里读到的,所以我不能回去重新阅读并自己弄清楚。
我有两个问题:
- 是否存在匿名函数可以使用足够的内存以使其值得关注的情况? (如果有,你有例子吗?)
- 匿名函数(相对于命名/静态函数)还有其他缺点吗?
最佳答案
所有 JavaScript 函数的行为方式都相同,因为它们继承了整个作用域链中的变量环境,直至并包括它们自身。这对于匿名函数和命名函数同样适用。
这个对外部环境的引用链保留在每个函数中,即使该函数被传递到一个完全不同的范围内。
传统上,这意味着只要内部闭包继续存在,任何给定链中的所有变量都会保留对它们的引用。尽管在编译代码的现代浏览器中,很可能会分析实际引用了哪些变量,并且只保留那些变量,允许对不再引用的其他变量进行垃圾回收。
但是,在其他情况下匿名函数是浪费的。
这是一段常见的代码:
for( var i = 0; i < 100; i++ ) {
(function( j ) {
setTimeout( function() { console.log( j ); }, 1000 );
})( i );
}
在这种情况下,匿名函数比命名函数更浪费,因为您在循环期间重新创建了 100 次相同的函数,而您可以重用命名函数。
function setConsole( j ) {
setTimeout( function() { console.log( j ); }, 1000 );
}
for( var i = 0; i < 100; i++ ) {
setConsole( i );
}
这具有完全相同的闭包开销,但效率更高,因为您只构造了一个函数来创建每个新的变量环境。
http://jsperf.com/immediate-vs-named (感谢 @Felix Kling 的 jsPerf。)
因此,特别是关于闭包,是的,只要您通过一些永久引用来维护闭包,就会有开销。我会说,如果可能的话,最好避免这种情况,但不要对此过于执着。有时,向作用域链添加新的变量环境就是最好的解决方案。
编辑: Here's an article from Google .具体来说,请参阅避免使用闭包的陷阱。有关扩展作用域链的性能影响的信息,以及匿名函数比命名函数“慢”的声明。
关于javascript - 在 JavaScript 中使用匿名函数有什么缺点吗?例如。内存使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6698386/