下一行的持续运营商是否存在分号插入危险?

时间:2014-07-21 05:22:04

标签: javascript newline ecmascript-5 code-formatting

从历史上看,我喜欢打破表达方式,以便继续显示“明显不完整”的偏见:

var something = foo + bar
    + baz(mumble);

这种态度来自于使用分号来终止表达式的语言。由于没有分号,第一行显然已经 不完整,因此最好向读者说明第二行不完整。

替代方案是:

var something = foo + bar +
    baz(mumble);

这对我来说不是那么好。现在唯一可以告诉baz(mumble);不是独立的(压缩一边)的方法是将你的眼睛扫描到前一行的末尾。 *(这可能很长,因为你需要首先打破它。)*

但是在奇怪的JavaScript领域,我开始看到人们将代码从看起来像第一种形式的东西改为第二种形式,并警告“自动分号插入”。它肯定会导致some surprising behaviors。当我把“学习自动分号插入是什么以及我是否也应该这样做”进入我的无限任务队列时,并不是真的想深入研究切线。

当我确实调查它时,我发现自己半确定......但不确定......我对它的使用方式没有危险。如果我在事故中遗漏了+并且写了:

,那么问题似乎就来了
var something = foo + bar
    baz(mumble);

...然后JavaScript会在foo + bar之后为您插入分号,因为这两行都是完整的表达式。我推断,或许那些其他JavaScript程序员认为将“明显有意不完整”的位偏向到将要继续的行的末尾更好,因为它精确定位了分号不是的位置

然而,如果我已经正确地阐述了我的前提,那么我正在以一种随后的线条“明显不完整”的方式塑造我的虚线。如果情况并非如此,那么我首先不会认为我的方式是优势。

我是否正确,我的方式不是我描述如何使用线条延续的条件的风险?在令人惊讶的方式中,是否存在任何“看似不完整”的表达陷阱?

要提供“以令人惊讶的方式完成”的示例,请考虑+ 1;是否可以单独解释为一行中的正数。它似乎可以:

plus one semicolon

但JSFiddle为此提供了回复:

var x = 3 + 2
+ 1;
alert(x)

也许这只是控制台中的一个怪癖,但它让我担心我的“只要第二行不是完整的表达式”解释就可以了。

2 个答案:

答案 0 :(得分:22)

如果您使用一些语法上有效的行并使用换行符标注它,则自动分号插入将不适用(除returnthrow之外的非常小的情况其他一些陈述,如下所列)。 ASI仅在绝对没有其他方式来解释代码时才会发生。当然,有一种方法可以将多行代码解释为单个语句,因为它作为单行有效。简而言之,ASI通常是解析器尝试理解程序的最后工具。

引用ES5,first case of ASI detailed in the spec发生......

  
      
  1. 当从左到右解析程序时,会遇到一个令牌(称为违规令牌),语法的任何产生都不允许 ...
  2.   

但是这种情况自然会被消除,因为在向其中注入换行符之前,你有一个语法上有效的行。因此,ASI的这种情况不适用于您的情况,因为它取决于没有分号的语法有效的代码范围。你在这里没有。

(其他两个案例也不适用;第二个案例适用于程序结束,第三个案例适用于continuebreakreturnthrow和后缀++ / --运营商。)

人们对ASI的常见问题发生在作者有两个行时,他们期望这些行分开,但这两行在理解为单行时碰巧没有语法问题。那个案子从两行开始,他们不小心变成了一行。你的情况是相反的:你从一行开始;它意外变成了两个。

答案 1 :(得分:15)

  

我开始看到人们将代码从第一种形式更改为第二种形式,并警告“自动分号插入”

那是垃圾。如果您有一个运算符(在任一行上),则不会有ASI - 请参阅What are the rules for JavaScript's automatic semicolon insertion (ASI)?

由于放置操作员的两种风格都可以使用,因此两者都被普遍接受,并且归结为个人/风格指南偏好。一旦你选择坚持它以保持一致性,你就已经命名了一些参数。

任何一方都没有“危险”,说实话,你不应该关心ASI。人们会因为a)他们不喜欢分号并期望自动插入而受到咬,但下一行是语法上有效的延续,或者b)他们在Allman风格的return语句之后编写对象/数组文字。