我之前从未见过这种语法,但它在整个Angular源代码中都得到了使用。
function something() {
// do stuff...
return function foo() {
// do stuff..
};
}
// later
var x = something();
从我所知道的foo()
被用作闭包函数,但为什么函数有一个名字?我认为给一个闭包函数一个名称是无效的语法,但这似乎在浏览器中正常运行。
上面和下面的代码有什么不同吗?如果是的话,是什么?
function something() {
// do stuff...
return function() {
// do stuff..
};
}
// later
var x = something();
答案 0 :(得分:5)
这与封闭中包含的函数无关。
功能声明:
之间存在真正的区别function myFunc() { /* ... */ }
和函数表达式:
var myFunc = function() { /* ... */ };
或
var myObj = {
myFunc: function() { /* ... */ },
// ...
}
在这些情况下,函数表达式是匿名的。您正在讨论的是命名函数表达式:
var myFunc = function privateName() { /* ... */ };
(请注意,内部privateName
不必与myFunc
匹配。)
与匿名相比,它们具有两个明显的优势,一个缺点。缺点是:
优点是:
这些名称显示在调试程序中,使您更容易找到自己的方式。
这些名称在函数内部可用,而在其他任何地方都没有,因此您可以使用它们
递归或其他内部使用,而不会污染全局命名空间
取决于argument.callee
等弃用的功能。
Kangax 或许写下了关于它们的权威性文章: Named function expressions demystified 。
答案 1 :(得分:3)
命名函数表达式是一件很酷的事情,它允许您通过使用相同的函数(递归调用)来简化缓存和调用。
例如,如果您想知道调用函数的次数,那该怎么办:
var anonNamedFn = function fn() {
fn.cache = fn.cache || {
callCount: 0
};
fn.cache.callCount += 1;
};
递归的另一个例子:
var anonNamedFn = function fn(n) {
if (n > 0) {
return fn(n-1);
}
};
它允许消除this
上下文的消歧。
<强>更新强>
它有助于调试,因为如果您选择明智的话,它会显示您的功能名称
但要小心,因为只有真正的浏览器才支持这个功能(IE9 + for IE)。
修改强> 匿名命名函数=&gt;命名函数表达式Paul S.