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

JavaScript匿名函数即时调用/执行(表达式与声明),javascript,anonymous-function,Javascript,Anonymous Function,可能的重复项: 为什么会这样: (function () { //code }()); 这是: var f = function () { //code }(); 有效,而这: function () { //code }(); 不是吗?它看起来完全相同-定义了匿名函数,并立即调用。有人可以引用JavaScript/ECMAScript标准来解释这一点吗 更新:谢谢大家的回答! 所以它是关于函数表达式与函数声明的比较。请参阅第13节,以及这篇伟大的文章: 重述答

可能的重复项:

为什么会这样:

(function () {
    //code
}());
这是:

var f = function () {
    //code
}();
有效,而这:

function () {
    //code
}();
不是吗?它看起来完全相同-定义了匿名函数,并立即调用。有人可以引用JavaScript/ECMAScript标准来解释这一点吗

更新:谢谢大家的回答! 所以它是关于函数表达式与函数声明的比较。请参阅第13节,以及这篇伟大的文章:

重述答案:

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

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

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


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

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

    举个例子:

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

    简单地说,任何时候你有一个单词
    函数
    ,前面没有任何东西,它就是一个声明。任何时候在它前面的东西都是一个表达式。

    匿名函数在堆栈溢出中得到了很好的解释
    问题。

    这里有一个简单的方法来考虑它:如果
    function
    是行中的第一个关键字,解析器将把行的其余部分解释为函数声明。换句话说,它会认为您正在尝试编写类似这样的内容,好像您忘记了命名函数:

    function foo(){ 
        // code
    }
    
    解决这个问题的方法是将整个函数包装在一些参数中,或者将其作为变量赋值的一部分。在这两种情况下,您都将
    函数
    放在行的后面,并允许解析器识别您没有编写函数声明

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

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


    第三种情况是函数degration语句,可以出现在任何可以有其他语句的地方(如
    if
    while
    语句)

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



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

    相关:那篇文章中接受的答案链接被破坏了。你的第一个例子也不起作用。结尾应该是}(),而不是}()@yoavmatchulsky第一个例子很好。外圆括号使其成为一个函数表达式,因此任何一种方法都有效;对于这个edge案例,根本没有理由使语言语法复杂化。为什么你会需要这个?@Tomalak Geret'kal有一个(尽管有疑问)原因:它是一致的,即没有标识符的任何东西都会被解释为表达式(因为没有标识符的声明无论如何都是无用的)。@Ixa:的确如此。也许更一致,但好处值得怀疑,那么为什么要使语法复杂化呢?@Tomalak Geret'kal,我个人认为语言设计者从未预料到自动执行匿名函数,所以我在这里没有发现任何错误。但我确实认为,它们要求将自动执行的匿名函数包装在paren中,这使得语法更加复杂。使用
    for
    对数组和对象进行迭代(而不是创建
    foreach
    )这一事实也表明了他们可能在这里使用的灵活性。当它在语法上与声明不同时,为什么要抛出异常呢。安德鲁:他们没有“要求”任何东西。您不必被迫使用这种可怕的语法。function声明语句不能声明匿名函数,因为否则以后没有人会得到对该函数的引用。实际上,它可以尝试:
    function(){}
    (但是它实际上是无用的,因为它既不能就地调用也不能以其他方式调用)更新:
    function(){}
    (即匿名声明)在Gecko中有效,但在Gecko中无效WebKit@Ixa:将帖子编辑得不那么模棱两可:)@PeterMortensen--wtf?不要对随机帖子进行毫无意义的编辑。