在 JavaScript 中使用匿名函数有什么缺点吗?例如.内存使用? [英] Are there any drawbacks to using anonymous functions in JavaScript? E.g. memory use?

查看:49
本文介绍了在 JavaScript 中使用匿名函数有什么缺点吗?例如.内存使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的某个时候,我读到了一些东西,这让我想到 JavaScript 中的匿名函数会消耗惊人的内存量(因为它们随身携带整个当前范围),而命名(静态?)函数没有这个问题.

At some point in the past, I read something that gave me the idea that anonymous functions in JavaScript can use up a surprising amount of memory (because they carry the entire current scope around with them), whereas named (static?) functions don’t have this issue.

我不记得我在哪里读到的,所以我不能回去重新阅读并自己弄清楚这一点.

I can’t remember where I read this, so I can’t go back and re-read it and figure this out for myself.

我有两个问题:

  1. 是否存在匿名函数可以使用足够内存而值得关注的情况?(如果有,你有例子吗?)
  2. 匿名函数(相对于命名/静态函数)还有其他缺点吗?

推荐答案

所有 JavaScript 函数的行为方式都相同,因为它们继承了整个作用域链中的变量环境,直至并包括它们自身.这对于匿名函数和命名函数同样适用.

All JavaScript functions will behave in the same manner in that they inherit the variable environments in entire scope chain leading up to, and including, themselves. This is equally true for both anonymous and named functions.

这个对外部环境的引用链与每个函数保持一致,即使该函数被传递到一个完全不同的范围.

This chain of references to the outer environments stays with each function, even if the function is passed into an entirely different scope.

传统上,这意味着只要内部闭包继续存在,任何给定链中的所有变量都会保留对它们的引用.虽然在编译代码的现代浏览器中,很可能会分析哪些变量被实际引用,只有那些会被保留,让其他不再被引用的变量被垃圾收集.

Traditionally, this would mean that all variables in any given chain have a reference retained to them as long as the inner closure continues to exist. Although in modern browsers that compile the code, it is likely that there will be an analysis of which variables are actually referenced, and only those will be retained, allowing others that are no longer referenced to be garbage collected.

然而,还有其他情况下匿名函数是浪费的.

However, there are other situations where an anonymous function is wasteful.

这是一段常见的代码:

for( var i = 0; i < 100; i++ ) {
    (function( j ) {
        setTimeout( function() { console.log( j ); }, 1000 );
    })( i );
}

在这种情况下,匿名函数比命名函数更浪费一点,因为您在循环期间重新创建了 100 次相同的函数,而您只能重用命名函数.

This is a situation where an anonymous function is a bit more wasteful than a named function because you're recreating an identical function 100 times during the loop when you could just reuse a named one.

function setConsole( j ) {
    setTimeout( function() { console.log( j ); }, 1000 );
}

for( var i = 0; i < 100; i++ ) {
    setConsole( i );
}

这具有完全相同的闭包开销,但效率更高,因为您只构建了一个函数来创建每个新的变量环境.

This has the exact same closure overhead, but is more efficient because you've only constructed one function to create each new variable environment.

http://jsperf.com/immediate-vs-named (感谢 @Felix Kling 提供 jsPerf.)

http://jsperf.com/immediate-vs-named (Thanks to @Felix Kling for the jsPerf.)

所以特别是关于闭包,是的,只要你通过一些永久引用维护闭包,就会有开销.我会说,如果可能的话,最好避免这种情况,但不要对此过于执着.有时,在作用域链中添加一个新的变量环境就是最好的解决方案.

So with respect to the closure in particular, yes there's overhead as long as you maintain the closure by some permanent reference. I'd say that it is good to avoid this if possible but not to be obsessive about it. Sometimes a new variable environment added to the scope chain is simply the best solution.

这是一篇文章来自 Google.具体来说,请参阅使用闭包避免陷阱.有关扩展作用域链对性能影响的信息,以及匿名函数比命名函数慢"的说法.

Here's an article from Google. Specifically, see Avoiding pitfalls with closures. for information on the performance impact of extending the scope chain, and for a claim that anonymous functions are "slower" than named functions.

这篇关于在 JavaScript 中使用匿名函数有什么缺点吗?例如.内存使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆