許多程式語言都有語句結束的概念。不過,用哪個符號結束以及結束語句的規則在各個語言之間存在差異。
對於 JavaScript 來說,它在這方面要求非常寬鬆。在 JavaScript 中語句結束符是分號,不過也可以不寫。它是怎麼做到的?JavaScript 編譯器是如何知道何時該結束一條語句呢?
它是通過一套簡單的規則和自動分號插入機制(Automatic Semicolon Insertion,簡寫為 ASI)實現的。我們先看一下分號的規則,然後了解一下 ASI 的機制。
分號的規則
分號用於標記一條語句的結束。
塊語句的末尾應該有一個分號。
分號的特殊案例。
上面的代碼是一個函數表達式,所以需要一個分號。
自動分號插入(Automatic Semicolon Insertion)
這是 Javascript 中的一種機制,它遵循一些規則,編譯器會嘗試把原始碼分解成語句。默認情況下,ASI 總是打開的。有時候自動分號插入機制很有用,但偶爾會遇到 ASI 改變語義引起的棘手問題。
ASI 規則
1. 遇到行結束符時,會插入一個分號。
2.遇到句法不允許的 『}』 時插入一個分號。
3.遇到一個 restricted production 後跟行結束符時,自動插入一個分號。
這些 restricted production 包括:++, --, continue, break, return, throw, yield 和 module 關鍵字。解析器遇到這些關鍵字後跟一個行結束符時,會在關鍵字後面插入一個分號。
但是需要注意 return 關鍵字:
上述代碼會在 return 語句後面插入一個分號,它會返回 undefined。return 後面的語句無法被訪問。為了避免這個問題,可以把上述2條語句寫在同一行。
依賴 ASI 可能導致的意外問題
如果我們不在代碼中寫分號,而是依賴 ASI,會偶爾遇到語義完全改變的情況。
意外的函數調用
意外的除法操作
意外的屬性訪問
結語
現在很多人選擇忽略分號,讓代碼看起來更簡潔。不過我建議始終明確寫上分號,以避免引起潛在的問題。