自動分號補齊(auto semicolon insertion,簡稱ASI)
在JavaScript中,行尾的分號有一種自動插入機制,如果新起了一行,并且這新的一行不能追加到當前語句時,會自動追加一個分號。但如果不加區(qū)分在每個表達式(Expression)和語句(statement)之后都手動輸入分號,那么其中絕大部分的分號是無用的。
導(dǎo)致上下文解析出錯時需要分號
會造成此類問題的token有6個:括號,方括號,正則開頭的斜杠,加號,減號,字符串模板的反引號。當以這6個字符作為一行開頭時,不會在上一行自動補全分號,造成解析出錯。
a = b
(c + d).toString()
會被解析成
a = b(c + d).toString()
即()會被看做是在調(diào)用函數(shù)b,和本意不符。所以應(yīng)盡量避免以這6個字符作為一行的開頭,如果避免不了,可以選擇在行首加分號。
絕對禁止的行結(jié)束符(restricted productions)
如果在不該換行的地方換行了,就會自動插入一個分號。
后綴表達式
左值表達式 [無行終結(jié)符] ++
左值表達式 [無行終結(jié)符] --
Continue 語句
continue [無行終結(jié)符] 標識符? ;
Break 語句
break [無行終結(jié)符] 標識符? ;
Return 語句
return [無行終結(jié)符] 表達式? ;
Throw 語句
throw [無行終結(jié)符] 表達式? ;
[無行終結(jié)符] 代表此處禁止換行。對于后綴表達式,遵循的原則是避免修改上一行的值。 對于 continue, break, return 和 throw,遵循的原則是:如果他們不帶參數(shù),他們不會指向下一行(會被插入一個分號)。
a
++
b
會被解析成
a;
++b
關(guān)于return 和 throw
function test() {
return
3
}
test()
輸出的結(jié)果實際是 undefined,因為上述代碼被解析成
function test() {
return;
3
}
test()
關(guān)于break 和 continue
var num = 0
outermost:
for(let i = 0, j; i < 100; i++) {
for(j = 0; j < 100; j++) {
if(i === 50 && j===50 ) {
break
outermost
}
num++
}
}
console.log(num)
此時break 和label標示符之間有一個換行符,此時會在break后自動補分號,outermost未起作用,輸出的結(jié)果為95。當break 和 label標示符放在同一行即 break outermost時,輸出結(jié)果為55。
因此筆者建議要有良好的編碼習(xí)慣,弄清ASI的規(guī)則,分號只加在必要的地方即可。