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

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

本文关键字:执行 表达式 声明 调用 函数 JavaScript      更新时间:2023-09-26

可能的重复:
JavaScript中的函数表达式和声明有什么区别
解释JavaScript';s封装的匿名函数语法

为什么:

(function () {
    //code
}());

这个:

var f = function () {
    //code
}();

工作,而这个:

function () {
    //code
}();

不是吗?它看起来完全一样——定义了匿名函数,并立即调用。有人能引用JavaScript/EMMAScript标准来解释这一点吗?

更新:感谢大家的回答!因此,这是关于函数表达式与函数声明。请参阅此堆栈;溢出答案,ECMAScript标准第13节,以及这篇伟大的文章:命名函数表达式的神秘化

概括答案:

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

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

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

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


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

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


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

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

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

举例说明:

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

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

这里有一个简单的方法:如果function是行上的第一个关键字,解析器将把行的其余部分解释为函数声明。换句话说,它会认为你正在尝试写这样的东西,就好像你忘记了给你的函数命名:

function foo(){ 
    // code
}

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

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

匿名函数在Stack Overflow中有很好的解释问题为什么需要在同一行调用匿名函数