从构造函数返回命名函数

时间:2014-04-09 13:38:14

标签: javascript

我之前从未见过这种语法,但它在整个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();

2 个答案:

答案 0 :(得分:5)

这与封闭中包含的函数无关。

功能声明

之间存在真正的区别
function myFunc() { /* ... */ }

函数表达式

var myFunc = function() { /* ... */ };

var myObj = {
    myFunc: function() { /* ... */ },
    // ...
}

在这些情况下,函数表达式是匿名的。您正在讨论的是命名函数表达式

var myFunc = function privateName() { /* ... */ };

(请注意,内部privateName不必与myFunc匹配。)

与匿名相比,它们具有两个明显的优势,一个缺点。缺点是:

  • IE,至少通过IE8,创建了两个这样的功能副本 对于你打算创造的每一个人。

优点是:

  • 这些名称显示在调试程序中,使您更容易找到自己的方式。

  • 这些名称在函数内部可用,而在其他任何地方都没有,因此您可以使用它们 递归或其他内部使用,而不会污染全局命名空间 取决于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.