小编典典

JavaScript 的自动分号插入 (ASI) 的规则是什么?

all

好吧,首先我可能应该问这是否取决于浏览器。

我已经读过,如果找到了一个无效的标记,但代码部分在该无效标记之前是有效的,如果它前面有一个换行符,则在该标记之前插入一个分号。

但是,由分号插入引起的错误引用的常见示例是:

return
  _a+b;

..这似乎不遵循这个规则,因为 _a 将是一个有效的令牌。

另一方面,分解调用链按预期工作:

$('#myButton')
  .click(function(){alert("Hello!")});

有没有人对规则有更深入的描述?


阅读 84

收藏
2022-03-09

共1个答案

小编典典

首先,您应该知道哪些语句会受到自动分号插入的影响(也称为 ASI):

  • 空语句
  • var陈述
  • 表达式语句
  • do-while陈述
  • continue陈述
  • break陈述
  • return陈述
  • throw陈述

ASI 的具体规则,在规范搂11.9.1 自动分号插入规则中进行了描述

描述了三种情况:

  1. 当遇到语法不允许的违规标记时,如果出现以下情况,则会在其前面插入分号:

  2. 该令牌与前一个令牌至少相隔一个LineTerminator

  3. 令牌是}

例如

    { 1
    2 } 3

被转化为

    { 1
    ;2 ;} 3;

满足第NumericLiteral 1一个条件,后面的记号是行终止符。满足第二个条件,下面的记号
是。2``}

  1. 当遇到输入标记流的结尾并且解析器无法将输入标记流解析为单个完整程序时,会在输入流的末尾自动插入分号。

例如

    a = b
    ++c

转换为:

    a = b;
    ++c;
  1. 这种情况发生在语法的某些产生式允许令牌,但产生式是 受限产生 式时,会在受限令牌之前自动插入分号。

限制生产:

    UpdateExpression :
        LeftHandSideExpression [no LineTerminator here] ++
        LeftHandSideExpression [no LineTerminator here] --

    ContinueStatement :
        continue ;
        continue [no LineTerminator here] LabelIdentifier ;

    BreakStatement :
        break ;
        break [no LineTerminator here] LabelIdentifier ;

    ReturnStatement :
        return ;
        return [no LineTerminator here] Expression ;

    ThrowStatement :
        throw [no LineTerminator here] Expression ;

    ArrowFunction :
        ArrowParameters [no LineTerminator here] => ConciseBody

    YieldExpression :
        yield [no LineTerminator here] * AssignmentExpression
        yield [no LineTerminator here] AssignmentExpression

经典的例子,带有ReturnStatement

    return 
      "something";

被转化为

    return;
      "something";
2022-03-09