为什么围绕JavaScript IIFE需要括号?

but*_*oys 10 javascript iife

我正在阅读JavaScript IIFE和迄今为止的理解概念,但我想知道外部括号.具体来说,他们为什么需要?例如,

(function() {var msg='I love JavaScript'; console.log(msg);}());
Run Code Online (Sandbox Code Playgroud)

效果很好,但是

function() {var msg='I love JavaScript'; console.log(msg);}();
Run Code Online (Sandbox Code Playgroud)

生成语法错误.为什么?关于IIFE的讨论很多,但我没有看到为什么需要括号的明确解释.

sle*_*man 10

有两种方法可以在JavaScript中创建函数(好吧,3,但是让我们忽略new Function()).您可以编写函数声明或编写函数表达式.

函数声明本身就是一个语句,语句本身不返回值(让我们也忽略调试控制台或Node.js REPL如何打印语句的返回值).然而,函数表达式是一个正确的表达式,JavaScript中的表达式返回可以立即使用的值.

现在,您可能已经看到有人说以下是函数表达式:

var x = function () {};
Run Code Online (Sandbox Code Playgroud)

结论语法可能很诱人:

function () {};
Run Code Online (Sandbox Code Playgroud)

是什么让它成为一种表达.但那是错的.上面的语法是使它成为匿名函数的原因.匿名函数可以是声明或表达式.使它成为表达式的是这种语法:

var x = ...
Run Code Online (Sandbox Code Playgroud)

也就是说,=标志右侧的所有内容都是表达式.表达式使编写语言中的数学公式更容易.因此,一般来说,预计数学处理的所有地方都是表达式.

JavaScript中的一些表达形式包括:

  • =操作员右边的一切
  • 大括号()中的东西不是函数调用大括号
  • 一切的数学运算符的右(+,-,*,/)
  • 三元运算符的所有参数 .. ? .. : ..

当你写:

function () {}
Run Code Online (Sandbox Code Playgroud)

它是一个声明,不返回值(声明的函数).因此,尝试调用非结果是一个错误.

但是当你写:

(function () {})
Run Code Online (Sandbox Code Playgroud)

它是一个表达式并返回一个值(声明的函数),它可以立即使用(例如,可以被调用或可以被赋值).

请注意上面表达式的规则.由此可见,大括号不是你可以用来构建IIFE的唯一东西.下面是构建IIFE的有效方法(因为我们编写函数表达式):

tmp=function(){}()

+function(){}()

-function(){}()

0/function(){}()

0*function(){}()

0?0:function(){}()

(function(){}())

(function(){})()
Run Code Online (Sandbox Code Playgroud)

实际上,您可能会+在第三方库中看到上述非标准表单之一(特别是版本),因为它们希望保存一个字节.但我强烈建议你只使用支撑形式(要么很好),因为它们被其他程序员广泛认可为IIFE.


All*_*hua 4

括在括号中的 IIFE 版本有效,因为这将内部函数声明标记为表达式。

http://benalman.com/news/2010/11/immediately-invoked-function-expression/

更详细的解释请参见:

高级 JavaScript:为什么这个函数要用括号括起来?

暗示:

调用运算符 (()) 仅适用于表达式,不适用于声明。