前言
相信從事過C#和Java的大家都知道分號是用作斷句(EOS,end of statement)的,而且必須加分號,否則編譯就不通過了。但JavaScript由于存在ASI機制,因此允許我們省略分號。ASI機制不是說在解析過程中解析器自動把分號添加到代碼中,而是說解析器除了分號還會以換行為基礎按一定的規則作為斷句的依據,從而保證解析的正確性。
規范理論
es5 標準定義了自動分號插入規則,包括以下三個基本規則加兩個前置條件:
前置條件
1、如果插入分號后解析結果是空語句,那么不會自動插入分號。
例子:(空語句,else 前不加分好)
if (a > b) else c = d
2、如果插入分號后它成為 for 語句頭部的兩個分號之一,那么不會自動插入分號。
例子:(不會加分號)
for (a; b )
基本規則
左到右解析程序,當遇到一個不符合任何文法產生式的 token(叫做 違規 token(offending token)),那么只要滿足下面條件之一就在違規 token 前面自動插入分號。
1、至少一個 LineTerminator 分割了違規 token 和前一個 token。
2、違規 token 是 }。
例子:(1、2不符合任何產生式,并且之間存在 LineTerminator,因此在違規 token 2前加了分好,2和}則是因為違規 token 是 }所以加了分號)
{ 12 } 3 { 1;2 ;} 3;左到右解析程序,tokens 輸入流已經結束,當解析器無法將輸入 token 流解析成單個完整 ECMAScript 程序 ,那么就在輸入流的結束位置自動插入分號。
對于受限產生式,也就是下面的5個,我們把產生式 [no LineTerminator here]后面的 token 叫做受限 token,如果在 token 和 受限 token 間存在了至少一個 LineTerminator,那么會在受限 token 前自動加上 token。
受限的產生式只限如下5個:
PostfixExpression :
LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] --
ContinueStatement :
continue [no LineTerminator here] Identifier;
BreakStatement :
break [no LineTerminator here] Identifier;
ReturnStatement :
return [no LineTerminator here] Expression;
ThrowStatement : throw [no LineTerminator here] Expression;
歸納
避免 ASI 帶來的問題
新聞熱點
疑難解答
圖片精選