關於JavaScript語句後面的分號

來源:互聯網
上載者:User

身為一個分號黨,我就不在嘮叨自己的看法了,為了讓我們的討論更有價值,我挖掘出來一些材料跟各位分享。

 JavaScript自動加分號規則,有3條

  1. 當有分行符號(包括含有分行符號的多行注釋),並且下一個token沒法跟前面的文法匹配時,會自動補分號。
  2. 當有}時,如果缺少分號,會補分號
  3. 當程式原始碼結束時,如果缺少分號,會補分號。

 

利用我自己的JS文法分析工具JSinJS(https://github.com/kissjs/JSinJS ),我求出了所有能夠出現在語句第一個的JS文法標記 (就是Statement的first集合),他們是:

["debugger", "try", "throw", "switch", "Identifier", "with", "return", "break", "continue", "for", "while", "do", "if", "new", "function", "(", "{", "[", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "this", "!", "~", "-", "+", "--", "++", "typeof", "void", "delete", ";", "var"]

共計35個。

 

我又求出了所有可以出現在分號之前的文法標記(即去掉分號以後的last集),他們是

["--", "++", "IdentifierName", "]", ")", "}", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "Identifier", "this", "debugger", "return", "break", "continue"]

共計17個。 

 

35*17 = 595種組合,為了方便記憶,以下我分組來討論文法歧義 。(本來用Excel弄了張表,不過表太大了不好貼出來)

 

首先,以下文法標記開頭的語句是絕對安全的,不會跟不加分號的上一行產生任何歧義:

var if do while for continue break return with switch throw try debugger ;

接下來我們來分組看不加分號導致的文法歧義:

  • 第一種是++和--兩種運算子出現在上一行結尾的情況,下一行以以下開頭時,會產生文法歧義: 
    function delete void typeof new null true false NumericLiteral StringLiteral RegularExpressionLiteral ( [ { Identifier ++ -- + - ~ ! 
    其中,function和delete是非常常用的statement開頭。
    特別是 ++和--單獨被斷為一行的時候,因為JS的文法規則規定後自增運算不允許中間插入換行,所以++和--會被視為前自增而跟下一行串連在一起。
  • 第二種是return作為上一行結尾的情況,下一行以以下開頭時,會產生文法歧義: function delete void typeof ( [ { Identifier ++ -- + - ~ !

    同樣因為JS文法的規則不允許在return 和後面的值之間插入換行,所以return之後只要有分行符號就會視為有分號,這常常會與使用者的期望不符合。

  • 第三種是下一行以+和-開頭的情況,上一行以以下結尾是,會產生文法歧義: -- ++ IdentifierName ] ) } RegularExpressionLiteral

    因為很少有語句以+或者-開頭,所以這種情況不算危險。

  • 第四種是上一行以break、continue結尾的情況,下一行以Identifier開頭時,會產生文法歧義。
  • 第五種是下一行以(和[開頭的情況,上一行以以下結尾是,會產生文法歧義: -- ++ IdentifierName ] ) } RegularExpressionLiteral StringLiteral NumericLiteral BooleanLiteral NullLiteral Identifier this 
    這種情況非常危險(所以hax的文章中要提出這種情況應該語句前寫分號),幾乎上一行的所有情況都將導致正常期望之外的結果。 
  • 第六種是,當下一行以RegularExpressionLiteral 開頭的情況,上一行的以下結尾,會導致/被理解為除號:
    -- ++ IdentifierName ] ) }  RegularExpressionLiteral StringLiteral NumericLiteral BooleanLiteral NullLiteral Identifier this 

總結,

 

  1. 在return、break、continue、後自增、後自減五種語句中,分行符號可以完全替代分號的作用。
  2. var if do while for continue break return with switch throw try debugger幾種關鍵字開頭的語句,以及空語句,上一行加不加分號影響不大。
  3. 凡運算式語句和函數運算式語句,後面不加分號非常危險,情況極其複雜。
  4. 凡(和[開頭的語句,前面不加分號極度危險。

 

以上是我整理的規則,不包含任何主觀論斷。加不加分號,終究還是各位看官自己決定。

練習題:

說出以下語句自動加分號正確的位置:

a+b 
a++ b 
this.a = o.a/[0-9]*/g.match(string)
function f() {    return /*     */ x }
(function f1(){})()(function f2(){})()
obj.if(a)/3/g .test(str)
this.call()[1,2,3].forEach(function(e){    console.log(e); })
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.