六角學院 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)?