立即函数调用语法


110

有一个JSLint选项,实际上是The Good Parts之一,它“ [需要]减少立即调用的次数”,这意味着构造

(function () {

  // ...

})();

而是需要写成

(function () {

  // ...

}());

我的问题是-谁能解释为什么第二种形式可能会更好?它更具弹性吗?容易出错?与第一种形式相比,它有什么优势?


自问了这个问题之后,我开始理解在功能值和功能值之间形成清晰的视觉区别的重要性。考虑一下立即调用的结果在赋值表达式的右侧的情况:

var someVar = (function () {

  // ...

}());

尽管从语法上讲,最外面的括号是不必要的,但是括号开头预先表明了所分配的值不是函数本身,而是函数被调用的结果。

这类似于Crockford关于构造函数的大写的建议-旨在作为查看源代码的任何人的视觉提示。


感谢您指出了这一点。我从来没有找到一种方法来摆脱JSLint的警告消息“在循环中创建函数时要小心”。我很小心,并确实将函数放在了结尾处,但JSLint仍然抱怨。现在我知道它假设我使用了第二种模式。
viam0Zah


我一直都在“做错”这件事。而且,当我说“所有时间”时,我从1995
Dave Land

Answers:


73

来自Douglass Crockford的样式约定指南:(搜索“立即调用”)

当要立即调用一个函数时,应将整个调用表达式包装在括号中,以便清楚地知道所产生的值是函数的结果,而不是函数本身。

因此,从根本上说,他认为这使功能值与功能值之间的区别更加清晰。因此,这是一个风格问题,而不是代码本身的实质差异。

更新的参考,旧的PPT不再存在


1
我很高兴我读了这篇。我刚读完Javascript:The Good Parts,而我一直想的是,分配调用函数的结果确实是一种糟糕的语法,因为您必须查看第一行和最后一行以了解正在发生的事情。他在书中没有使用包装纸,但我确切地知道了他为什么推荐它们。
Skilldrick 2010年

2
@altCognito,您可以为PPT提供新的链接吗?
th1rdey3

1
我浏览了整个网络,但仍然找不到该PPT的副本
Forethinker 2014年

1
我找不到原始的PPT,但可以在他的javascript约定指南中找到相同的点。
cgp 2014年

archive.org有吗?
约翰·格林

2

立即调用匿名函数将其包装在括号中,原因是:

  1. 它们是函数表达式,如果忽略括号,则会将其解释为函数声明,这是一种语法错误。

  2. 函数表达式不能以单词function开头。

  3. 在将函数表达式分配给变量时,不返回函数本身,而是返回函数的返回值,因此家长会评估其中的内容并产生一个值。当函数执行时,尾部的括号..}()使函数立即执行。


Dathan,您正在回答另一个问题。您是正确的,有时在语法上必须加上括号,以便解析器可以将函数表达式与函数声明区分开。但是我的问题是关于调用括号的位置。您的第三点是不准确的;在这种情况下,不需要括号。
Bobby Eickhoff 2012年

我正在回答您的第一个示例,其中立即调用匿名函数未分配给变量,因此出于前两个原因,括号在语法上是必需的。第三个原因只是恢复了您甚至所说的话:“左括号预先表明,分配的值不是函数本身,而是函数被调用的结果。” 但我想还不清楚。
丹丹(Dathan)2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.