JS分號自動插入的ASI機制

2021-09-13 12:45:25 字數 1889 閱讀 6145

規範理論

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 是 }所以加了分號)

3 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帶來的問題

1、字尾運算子 ++ 或 -- 和它的運算元應該出現在同一行。

2、return 或 throw 語句的表示式開始位置應該和 return 或 throw token 同一行。

3、break 或 continue 語句的標示符應該和 break 或 continue token 同一行。

何時加分號

在以 ([/+- 開頭的語句前加分號(由於正常寫法均不會出現以 .,*% 作為語句開頭,因此只需記住前面5個即可,你看能懶則懶哦)

不過這裡只考慮了換行的情況,其實 asi 還存在不換行的情況,這就要根據標準裡的三條規則行事了!

知道了這點,其實我們就可以省略大部分的分號了。但是也不強求,因為這還是要根據個人習慣以及團隊風格走的。

小補充

為什麼自執行函式前要加分號?

主要是應對**合併壓縮時,由於缺少分號;帶來的錯誤。知道了上面的規則,在 ( 開頭的行前加分號就可以避免錯誤了。

JS自動插入分號規則

首先應該知道哪些語句會用到自動插入分號 automatic semisolon insertion,asi 空語句 var語句 表示式 do while語句 continue語句 break語句 return語句 throw語句 asi的具體規則,在此規範中描述 11.9.1 rules of au...

JS自動填寫分號導致的坑

js中會自動清除句子和句子之間的空格以及tab縮排,這樣就可以允許使用者編寫的 更加隨性和更加可讀,在該行 解析的時候如果該行 可以解析,就會在該行 最後自動填寫分號,如果該行 無法解析就會把該行 和下一句 合併,直到 可以解析 js中如果乙個語句以 開頭,就有可能與上一句合在一起解析 也因為js會...

JS傳遞陣列自動以分號分隔

今天在家做公司的專案,遇到乙個很奇怪的事,其中js傳遞陣列時,傳遞過去的資料會以,分號 分隔。如下 function expertopinion var url servlet makescoreaction var paras iditem iditem idoperate idoperate o...