六角學院 JS 核心筆記 (十一)【運算子、型別與文法】- ASI 自動插入分號
ASI 是什麼?
ASI 即 Automatic Semicolon Insertion,當程式碼沒有加上分號時,依照 ASI 的規則,自動插入分號。它會帶來一些好處,但是也會造成一些問題。
舉例
1 | function test() { |
原本是預期輸出結果為 I am Jenifer.,但是卻變成 undefined,為什麼???
因為 ASI 的緣故,自動在 return 的後面加上分號,變成如下:
1 | function test() { |
沒有真的回傳字串,當然不會出現如我們預期的結果。
規則
根據 JavaScript: The Definitive Guide, 6th Edition, David Flanagan, O’Reilly, 2011 提到如下:
JavaScript does not treat every line break as a semicolon: it usually treats line breaks as semicolons only if it can’t parse the code without the semicolons.
JavaScript 不會將每個換行都視為分號:只有當,兩行或多行之間沒有分號,卻也無法從語法上去解析程式碼時,它才會將換行視為分號。
例如下方第一、二行之間,就是符合上述情況。但是二、三、四行之間,雖然沒有分號,但是可以從語法上去解析程式碼,因此不會將換行視為分號,他們可以被解析成 a = 3;。
1 | var a |
但是上述規則有兩個例外。
例外一
return、break 和 continue 語句,遇到換行,就會被插入分號。不會跟下面一行的語句一起解析。
像是我們上面提到的 return 例子。return 和下一行的 "I am Jenifer." 中間沒有分號,而且可以從語法上去解析程式碼,應該要被解析成 return "I am Jenifer.";,但是卻沒有!
1 | return |
例外二
++ 和 −− 運算子不會被加在句子尾端。
下方的例子中,x 和下一行的 ++ 中間沒有分號,而且可以從語法上去解析程式碼,應該要被解析成 x++;,但是卻沒有!因為 ++ 運算子不會被加在句尾,因此下方只會被解析成 x; ++y;。
1 | x |
「不會」加入分號的地方
- 下一行是
(、[、/開始 (容易出錯的地方) - 下一行以
+、-、*、%作開始 (會影響執行結果) - 下一行以
,、.作開始 (需注意執行結果)
上述三個需要注意的地方,仔細想想都是很合理的,例如:
1 | test |
如果 test 是函式名稱,應該要被解析成 test();;但是如果它不是函示,就會報錯 Uncaught TypeError: test is not a function。
還有一個例子是立即函式:
1 | var name = "Jenifer" |
第一、二行之間沒有分號,( 可以從語法上去解析成要呼叫函式,但是 "Jenifer" 不是函式,因此會出錯。
總而言之,就是乖乖在正確的地方加分號就好了阿~(攤手
更完整的規則內容,請參考 11.9.1Rules of Automatic Semicolon Insertion
參考資料:
六角學院:JavaScript 核心篇 - 邁向達人之路
What are the rules for JavaScript’s automatic semicolon insertion (ASI)?