解释了自执行函数语法和回调语法

或许有点愚蠢的问题。

但是我想理解为什么自执行函数的语法和它所拥有的回调与所有其他JS语法的不同之处。

(function () { })() 

我只需要理解为什么它有效地封装它()我不会猜到它是有效的,然后后面的额外()回调,(它只是直接位于它之后,我也不会期望有效。

有人能够向我解释这个吗?

function (...) {...}部分是函数表达式 ,即表示函数的表达式。 在这种情况下,必须用括号括起来的唯一原因是,如果关键字function是语句中的第一个东西,那么该语句被假定为函数语句 ,即函数声明。 (实际上,它不一定要用括号括起来;它也可以用一个+作为前缀,或者通常在function之前放置任何类型的令牌来阻止函数语句解释。)

函数表达式后面的()部分与调用函数的normal ()部分相同。 这个:

 (function (...) {...})(...); 

是(除了临时变量)与此相同:

 var f = function (...) {...}; f(); 

这相当于:

 function f(...) {...}; f(); 

本质上,外括号允许完全解释和实例化函数对象,这样一旦退出这些括号的范围,就可以调用函数对象了。

看这里:

  • 为什么需要在同一行上调用匿名函数?

当您声明时,您将其用作函数表达式(从上面的链接定义函数的第三种方式)。 与任何表达式一样,此(expression)求值为表达式 – 此处使用的括号是必要时建立优先级。 所以你可以写这个例子:

 var f = function(a) { var s = (((( 1 )))) + (((( a )))); console.log(s); }; ((((( f ))))) (2); 

( 实例 )然后删除具有相同结果的所有不必要的括号(基本上是打印1 + 2 = 3 )。 的结果:

 (function(...) { ... }) 

是一个接受一些参数并具有要执行的主体的函数。 这个:

 (function(...) { ... })() 

几乎相当于:

 var f = (function(...) { ... }); // Now f is a function that can be called f(); 

匿名函数是有用的,其中包括两个原因 – 它们是匿名的(即它们不创建其他名称 – 再次参见上面的SOq链接),它们是其他不需要全局的东西的“容器” 。

你在这里有一个立即调用的函数表达式,也称为IFFE(读取iffy),是一个使用JS函数作用域生成词法作用域的设计模式。 这些用于避免变量提升,污染全局环境并同时允许公共访问方法,同时保留在函数中声明的变量的本地隐私。 理解这一点的关键是JS具有函数作用域而不是块作用域,并通过引用在闭包内传递值。 您可以在立即调用的函数表达式中进一步阅读此内容。