部分取决于您使用的是函数表达式还是函数声明。它们是不同的东西,它们发生在不同的时间,它们对周围的范围有不同的影响。因此,让我们从区别开始。
函数表达式是一种function
将结果用作右手值的产生式——例如,您将结果分配给变量或属性,或将其作为参数传递给函数等。这些都是函数表达式:
setTimeout(function() { ... }, 1000);
var f = function() { ... };
var named = function bar() { ... };
(不要使用最后一个 - 称为命名函数表达式 - 实现有错误,尤其是 IE。)
相反,这是一个函数声明:
function bar() { ... }
它是独立的,您没有将结果用作右手值。
它们之间的两个主要区别:
函数表达式在程序流中遇到的地方进行求值。当控制进入包含范围(例如,包含函数或全局范围)时,会评估声明。
函数的名称(如果有的话)在函数声明的包含范围中定义。它不适用于函数表达式(除非浏览器错误)。
您的匿名函数是函数表达式,因此除非解释器进行优化(这是免费的),否则它们将在每个循环中重新创建。因此,如果您认为实现会优化,那么您的使用就很好,但是将其分解为命名函数还有其他好处,而且——重要的是——不会花费你任何费用。此外,请参阅casablanca 的回答,了解为什么解释器可能无法优化在每次迭代中重新创建函数,具体取决于它检查代码的深度。
更大的问题是,如果您在循环中使用函数声明、条件主体等:
function foo() {
for (i = 0; i < limit; ++i) {
function bar() { ... } // <== Don't do this
bar();
}
}
从技术上讲,仔细阅读规范的语法表明这样做是无效的,尽管实际上没有实现实际上强制执行。实现的功能是多种多样的,最好远离它。
为了我的钱,最好的选择是使用单个函数声明,如下所示:
function foo() {
for (i = 0; i < limit; ++i) {
bar();
}
function bar() {
/* ...do something, possibly using 'i'... */
}
}
您会得到相同的结果,实现不可能在每个循环上创建一个新函数,您会从具有 name 的函数中受益,并且不会丢失任何东西。