Javascript 从构造函数返回命名函数

Javascript 从构造函数返回命名函数,javascript,Javascript,我以前从未见过这种语法,但在Angular源代码中都使用过 function something() { // do stuff... return function foo() { // do stuff.. }; } // later var x = something(); 据我所知,foo()被用作闭包函数,但为什么函数有名称呢?我认为给闭包函数命名是无效的语法,但在浏览器中运行良好 上面的代码和下面的代码有什么不同吗?如果是,什么 funct

我以前从未见过这种语法,但在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();
命名函数表达式是一个很酷的东西,它允许您轻松地使用同一个函数(递归调用)进行缓存和调用

例如,如果您想知道函数被调用了多少次,该怎么办:

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);
    }
};
它允许消除
上下文的歧义。

更新

它有助于调试,因为如果您选择了一个明智的函数,它会显示您的函数名

不过要小心,因为只有真正的浏览器才能很好地支持此功能(IE的IE9+)

编辑
匿名命名函数=>命名函数表达式

这与包含在闭包中的函数无关

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

function myFunc() { /* ... */ }
var myFunc = function() { /* ... */ };
var myFunc = function privateName() { /* ... */ };
和函数表达式:

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

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

function myFunc() { /* ... */ }
var myFunc = function() { /* ... */ };
var myFunc = function privateName() { /* ... */ };
(请注意,内部
privateName
不必匹配
myFunc

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

  • IE至少通过IE8创建了这类函数的两个副本 为每一个你想要创造的人
优点是:

  • 调试器中会显示这些名称,使您更容易找到解决方法

  • 这些名称在函数内部可用,在其他任何地方都不可用,因此您可以将它们用于 递归或其他内部用法,而不会污染全局命名空间,也不会 取决于不推荐使用的功能,如
    参数.callee


可能写了一篇关于它们的权威性文章:

好吧,既然你没有执行函数,那么下面示例中的x将是函数定义,不是吗?它可能是一种维护数据处理范围的用途,因为某些变量仍在该范围内,它只是移动到其他地方?我也希望在可能的情况下得到启发-但。。如果它有名字就不是匿名的。是的,这是我喜欢的关于彩虹的东西。我想你要找的术语是命名函数表达式(使用
函数
作为运算符)。IE“劣势”只是一个问题,如果你因为它而有名字冲突。如果你期待IE,那就允许吧,否则就充分利用它们吧!不过,“函数声明”仍然是一个有效的表达式。它的计算结果是函数。您想强调的是命名函数表达式和匿名函数表达式之间的区别。命名函数与当前对象的原型有关系吗?@PaulS:如果您阅读kangax的文章,您可能会认为这是一个更大的缺点,即使在仅限IE的情况下。@Aryehleibtaulog:您是对的。这篇文章的序言太长了。当真正的问题仅仅是命名函数表达式和匿名函数表达式之间的差异时,可能没有真正的理由去讨论函数声明和函数表达式之间的差异。