javascript匿名函数立即调用/执行(表达式与声明)

JavaScript anonymous function immediate invocation/execution (expression vs. declaration)

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicates:
What is the difference between a function expression vs declaration in JavaScript?
Explain JavaScript's encapsulated anonymous function syntax

为什么:

1
2
3
(function () {
    //code
}());

而这:

1
2
3
var f = function () {
    //code
}();

有效,而这:

1
2
3
function () {
    //code
}();

不是吗?它看起来完全相同-匿名函数被定义并立即调用。有人能从解释这一点的javascript/ecmascript标准中报价吗?

更新:谢谢大家的回答!关于函数表达式和函数声明。请参阅此堆栈溢出答案、ECMAScript标准第13节和这篇伟大的文章:命名函数表达式已解除定义。

总结答案:

  • 第一个代码段被解释为一个表达式,因为应用了分组运算符()——见ECMAScript标准第11.1.6节。

  • 在第二个代码片段中,函数被解释为表达式,因为它位于赋值运算符=的右侧。

  • 第三个代码段没有任何允许解释器将函数作为表达式读取的内容,因此它被认为是一个声明,没有标识符是无效的(gecko允许它通过,但是它会阻塞后面的()分组运算符(如它认为的)不适用于任何内容)。


  • 前两种情况显示函数表达式,并且可以出现在像(1+1x*f(4)这样的表达式出现的任何地方。就像1+12的计算一样,这些表达式对相应的函数进行计算。

    第三种情况是函数声明,可以出现在任何可以有其他语句的地方(如ifwhile语句)。

    尝试通过funcion声明语句声明匿名函数没有多大意义,因为否则之后没有人会得到对该函数的引用。

    在前两种情况中,您需要打开(var x =的原因是它们强制在表达式上下文中解析下一位。(例如,想想你怎么做不到。如果你只是把function作为第一件事,它将被解析为你不想要的声明语句。


    前两个被称为函数表达式,这意味着它是内联的,并被解释为JS代码运行。

    第三个是函数声明,在编译代码时进行解释。因为它是在编译时解释的,所以您不能立即运行它,因为它周围的其他代码都没有运行过。

    举例说明:

    1
    2
    3
    4
    5
    6
    7
    8
    // foo == undefined
    // bar == function

    function bar(){ .. }
    var foo = function(){ ... }

    // foo == function
    // bar == function

    简单地说,任何时候如果你有一个单词function,前面没有任何内容,它就是一个声明。任何时候在它之前,它都是一种表达。


    这里有一个简单的方法来考虑它:如果function是行中的第一个关键字,解析器将把行中的其余部分解释为函数声明。换言之,它会认为您正试图写这样的东西,好像您忘记了命名您的函数:

    1
    2
    3
    function foo(){
        // code
    }

    解决这个问题的方法是要么将整个函数包装在一些parens中,要么将其作为变量赋值的一部分。在这两种情况下,您都将function放回行中,并允许解析器识别您没有在编写函数声明。

    允许function出现在一行的开头,并且仍然区分函数表达式和函数声明,这对我来说似乎是微不足道的,但我猜在最初设计JavaScript时,这并不是那么微不足道。


    在堆栈溢出中很好地解释了匿名函数问:为什么需要在同一行上调用匿名函数?.