Logo
Section 1 / 12

注意换行的位置

了解分号和换行符在 JavaScript 中的作用。

导入

注意换行的位置

了解分号和换行符在 JavaScript 中的作用。

引言

一些动态类型编程语言对分号不敏感,将其视为可选语法。但 JavaScript 并非如此。分号并非可选。在某些位置,分号至关重要;而在其他位置,它更多是一种风格选择。然而,如果你在需要分号的地方遗漏了它,JavaScript 不会报错。这是因为 JavaScript 遵循一种理念:与其抱怨,不如默默“报复”。

📝注意:仅仅简单地添加一个 ; 并不够。我们必须真正理解 JavaScript 的
自动分号插入(ASI) 规则。

JavaScript 的自动分号插入(ASI)规则

ASI 规则的两个核心要点如下,并附有示例说明:

第一条规则

一个有效的程序以分号结尾。如果某个脚本没有以分号结束,JavaScript 会自动插入一个分号。由于代码是从左到右逐个解析的,当遇到一个意外的标记,且该标记与前一个标记之间存在换行符时,JavaScript 会在该标记之前自动插入一个分号。

示例

例如,考虑以下代码片段:

1// 有错误的代码 2const unexpected = function() { 3 let first 4 second = 1; 5 6 console.log(first); 7 console.log(second); 8} 9 10unexpected(); 11console.log(second);

解释

  • 我们使用 let 和 const 而不是 var——这是这段代码的优点。
  • 然而,first 之后出现的 second 标记是不符合预期的,尽管两者之间有换行。因此,JavaScript 在 second 变量前悄悄插入了一个分号。这导致 first 的值为 undefined,而 second 变成了全局变量——后果严重。
  • 上述代码块的输出结果清楚地展示了这一点。

第二条规则

如果候选标记是 break、continue、return、throw 或 yield,并且该标记与下一个标记之间存在换行符,JavaScript 会自动在候选标记后插入一个分号。

示例

例如,以下代码中的第二个 return(第9行)写法不正确:

1// 有错误的代码 2const compute = function(number) { 3 if(number > 5) { 4 return number 5 + 2; // <label id="code.plus2" /> 6 } 7 8 if(number > 2) { 9 return 10 number * 2; 11 } 12}; 13 14console.log(compute(6)); 15console.log(compute(3));

解释

  • 由于第二个 return 后面紧跟着换行符,JavaScript 会在 return 后自动插入一个分号。因此,函数返回的是空值,即 undefined,这可以从代码块的输出中看出。

  • 在第一个 return 中,虽然该行没有分号,但由于 + 可以合法地紧跟在 number 之后,所以不会在此处插入分号。不过,如果将第5行的 + 2 改为 2,JavaScript 就会在 2 前插入一个分号,导致结果为 6,而不是因为发现不可达代码而报错。

建议

以下是一些有助于做出最佳决策的建议:

  • 如果某行代码较短,应以清晰可见的分号结尾。按惯例,我们不在结束代码块的 } 之后添加分号。
  • 如果某行代码较长,应将其拆分为多行,但要确保拆分方式不会导致 JavaScript 因自动插入分号而偏离你的本意。

结语

从上述示例可以看出,问题并不在于分号是否可选,而在于我们如何断行。这种陷阱很容易陷入,但通过使用 lint 工具可以有效避免此类错误。

入门

使用 === 代替 ==