小白隨機(jī)在互聯(lián)網(wǎng)上亂丟一些賽博垃圾,還望撥冗批評(píng)斧正。
?要不要加分號(hào)?
? ? ? ? 先說結(jié)論:“不引起程序出錯(cuò)的前提下,加不加都可以,按自身習(xí)慣來?!?
為什么JS可以不加分號(hào)?
?????????實(shí)際上,行尾使用分號(hào)的風(fēng)格來自于Java,也來自于C和C++,這一設(shè)計(jì)最初是為了降低編譯器的工作負(fù)擔(dān)。
????????但是,從今天的角度來看,行尾使用分號(hào),其實(shí)是一種語(yǔ)法噪音,恰好JavaScript語(yǔ)言有提供了相對(duì)可用的分號(hào)自動(dòng)補(bǔ)全規(guī)則,所以,很多JavaScript程序員都是傾向于不加分號(hào)的。
? ? ? ? 由于我是一個(gè)大二的萌新,此前只接觸過C語(yǔ)言,所以個(gè)人編碼習(xí)慣還是會(huì)在能加分號(hào)的地方都加上分號(hào),目前為止這種編碼習(xí)慣沒有帶來過什么麻煩。那么,為什么JS不像C語(yǔ)言一樣非要老老實(shí)實(shí)加分號(hào)呢?
自動(dòng)插入分號(hào)規(guī)則
自動(dòng)插入分號(hào)規(guī)則獨(dú)立于所有的語(yǔ)法產(chǎn)生式定義,規(guī)則有三條:
有換行符,且下一個(gè)符號(hào)是不符合語(yǔ)法的,那么就嘗試插入分號(hào)。
有換行符,且語(yǔ)法中規(guī)定此處不能有換行符,那么就自動(dòng)插入分號(hào)。
源代碼結(jié)束處,不能形成完整的腳本或者模塊結(jié)構(gòu),那么就自動(dòng)插入換行符。
這樣描述是比較難以理解的,我們一起看一些實(shí)際的例子進(jìn)行分析。
let a = 1
void function(a){
console.info(a);
}(a)
在這個(gè)例子中,第一行結(jié)尾處有換行符,接下來 void 關(guān)鍵字接在 1 之后是不合法的,這里命中了我們的第一條規(guī)則,因此會(huì)在 void 前插入換行符。
var a = 1,b = 1, c = 1;
a
++
b
++
c
這也是個(gè)著名的例子,我們看到第二行的a之后,有換行符,后面遇到了++運(yùn)算符,a后面跟++是合法的語(yǔ)法,但是事實(shí)上,在編譯的時(shí)候,這里的 a 的后面會(huì)插入一個(gè)分號(hào)。所以這段代碼最終的結(jié)果,b 和 c 都變成了2,而 a 還是1,引發(fā)了錯(cuò)誤。那么,什么情況下JS不加分號(hào)會(huì)出錯(cuò)呢?
什么情況下不加分號(hào)會(huì)出錯(cuò)
1. 小括號(hào)開頭的前一條語(yǔ)句
想說的一點(diǎn)是,為什么匿名函數(shù)前面要加分號(hào);
假設(shè):如果不加分號(hào),程序最終編譯成這樣子:
var a = 4 console.log(a)(function () {...}
結(jié)果就會(huì)報(bào)錯(cuò):Uncaught TypeError: console.log(...) is not a function
Why?
那是因?yàn)槟涿瘮?shù)是以括號(hào)()為開頭,對(duì)于程序括號(hào)()代表函數(shù)執(zhí)行,那前面應(yīng)該就有函數(shù)名,編譯后空格去掉就console.log(a)(...)
,自然報(bào)錯(cuò)。
這也是為什么JS語(yǔ)句后要加分號(hào)的原因。
那我不想在每條語(yǔ)句(console.log(a)
)后都加分號(hào)怎么辦?
就需要在匿名函數(shù)前加分號(hào),后面不加就前面加。
再來一條例子看看:這就是小括號(hào)開頭的前一條語(yǔ)句要加分號(hào)。(匿名函數(shù))
2. 中方括號(hào)開頭的前一條語(yǔ)句
當(dāng)然,解決方法就是在行首加分號(hào)。
3.?以 "(" ,"[" , "/" , "+" , "-" 開始的語(yǔ)句
以 "(" ,"[" , "/" , "+" , "-" 開始的語(yǔ)句,極有可能和前面一條語(yǔ)句一起解析。
如果前一條語(yǔ)句無法和后一條語(yǔ)句合并解析,JavaScript才會(huì)在第一條語(yǔ)句后插入分號(hào),這是通用規(guī)則。
但是,有2個(gè)例外,
3.1 return ,break和continue
如果涉及 return 、break、continue 時(shí),如果這三個(gè)關(guān)鍵字后緊跟換行,則該關(guān)鍵字后一定會(huì)插入分號(hào);
return true
一定會(huì)被解析成
return; true;
這顯然違背了代碼的本意。
3.2 有 ”++“ 或 ”--“運(yùn)算符時(shí)
如果涉及 ”++“ ,”--“運(yùn)算符的時(shí)候,這些表達(dá)式可以作為表達(dá)式的前綴,也可以作為表達(dá)式的后綴。
如果將其作為表達(dá)式的后綴的話,它和表達(dá)式應(yīng)該在同一行,否則,JavaScript會(huì)在行末添加添加分號(hào),并且 ”++“ "--"會(huì)被作為下一句的前綴操作符與下一句一起解析。
x
++
y
這段代碼解析為:
x; ++y;
看完這么多,我還是決定繼續(xù)老老實(shí)實(shí)地給JS加分號(hào)了。。。
文章來源:http://www.zghlxwxcb.cn/news/detail-807930.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-807930.html
到了這里,關(guān)于Javascript,到底要不要寫分號(hào)?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!