【问题标题】:Immediate function invocation syntax立即函数调用语法
【发布时间】:2023-10-30 20:06:02
【问题描述】:

有一个JSLint 选项,实际上是 The Good Parts 之一,它“[需要] parens around immediate invocations”,这意味着构造

(function () {

  // ...

})();

应该写成

(function () {

  // ...

}());

我的问题是——谁能解释为什么第二种形式可能被认为更好?是不是更有韧性?更不容易出错?它比第一种形式有什么优势?


自从提出这个问题后,我开始明白在函数值和函数值之间进行清晰的视觉区分的重要性。考虑立即调用的结果是赋值表达式右侧的情况:

var someVar = (function () {

  // ...

}());

虽然最外面的括号在语法上是不必要的,但左括号给出了一个预先指示,即被分配的值不是函数本身,而是被调用的函数的结果。

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

【问题讨论】:

标签: javascript syntax jslint iife


【解决方案1】:

来自 Douglass Crockford 的 style convention guide:(搜索“立即调用”)

当要立即调用一个函数时,整个调用表达式应该用括号括起来,这样就可以清楚地看出生成的值是函数的结果,而不是函数本身。

所以,基本上,他觉得它更清楚地区分了函数值和函数值。所以,这是一个风格问题,而不是代码本身的实质性差异。

更新参考,旧PPT不存在了

【讨论】:

  • 很高兴我读到了这篇文章。我刚刚读完 Javascript: The Good Parts,我一直在想,分配调用函数的结果是非常糟糕的语法,因为您必须查看第一行和最后一行才能了解正在发生的事情。他没有使用书中的包装括号,但我明白他为什么推荐它们。
  • @altCognito,你能提供一个新的PPT链接吗?
  • 我浏览了网页,但还是找不到那个PPT的副本
  • 我没找到原版的PPT,但是我在他的javascript约定指南中找到了相同的点。
  • archive.org 有吗?
【解决方案2】:

立即调用的匿名函数将其包裹在括号中,因为:

  1. 它们是函数表达式,省略括号会导致它被解释为函数声明,这是一个语法错误。

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

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

【讨论】:

  • Dathan,你在回答另一个问题。您是正确的,括号有时在语法上是必需的,因此解析器可以将函数表达式与函数声明区分开来。但我的问题是关于调用括号的位置。你的第三点不准确;在这种情况下,括号是不必要的。
  • 我在回答您的第一个示例,其中立即调用匿名函数未分配给变量,因此括号在语法上是前两个原因所必需的。第三个原因只是恢复了您所说的内容:“左括号预先指示分配的值不是函数本身,而是调用函数的结果。”但我想还不清楚。
【解决方案3】:

或者,使用:

void function () {
...
} ()

【讨论】: