从构造函数返回命名函数

Rea*_*lar 4 javascript

我以前从未见过这种语法,但它在整个Angular源代码中都得到了使用.

function something() {
    // do stuff...
    return function foo() {
        // do stuff..
    };
}

// later
var x = something();
Run Code Online (Sandbox Code Playgroud)

从我所知道的foo()是用作闭包函数,但为什么函数有一个名字?我认为给一个闭包函数一个名称是无效的语法,但这似乎在浏览器中正常运行.

上面和下面的代码之间有什么不同吗?如果是的话,什么?

function something() {
    // do stuff...
    return function() {
        // do stuff..
    };
}

// later
var x = something();
Run Code Online (Sandbox Code Playgroud)

Sco*_*yet 5

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

函数声明之间存在真正的区别:

function myFunc() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

和一个函数表达式:

var myFunc = function() { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

要么

var myObj = {
    myFunc: function() { /* ... */ },
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

var myFunc = function privateName() { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

(注意内部privateName不必匹配myFunc.)

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

  • IE,至少通过IE8,为你想要创建的每一个创建了两个这样的函数副本.

优点是:

  • 名称显示在调试器中,使您更容易找到自己的方式.

  • 这些名称在函数内部以及其他任何地方都可用,因此您可以将它们用于递归或其他内部使用,而不会污染全局命名空间,也不会依赖于已弃用的功能argument.callee.

Kangax或许写了关于它们的权威文章:命名函数表达式揭秘.