JavaScript中分號(hào)的一些細(xì)節(jié)
前言
JavaScript 中的分號(hào)是可選的,加不加分號(hào)主要是個(gè)代碼風(fēng)格問(wèn)題。一種風(fēng)格是使用分號(hào)明確結(jié)束語(yǔ)句,即便這些分號(hào)不是必需的;另一種風(fēng)格是盡可能的不加分號(hào),只在必要的情況才加。我個(gè)人就不喜歡加分號(hào),當(dāng)然喜歡加分號(hào)的朋友也不少。無(wú)論你喜歡哪種風(fēng)格,都需要了解了解 JavaScript 中的分號(hào)的一些細(xì)節(jié)。
代碼中分號(hào)的作用
分號(hào)的主要作用是:作為語(yǔ)句的斷言(EOS)用于結(jié)束一個(gè)程序語(yǔ)句,目的是讓解析器正確解析程序。在很多 C-Style 語(yǔ)言里,用分號(hào)明確結(jié)束一行語(yǔ)句,主要是為了降低語(yǔ)言編譯器開發(fā)的成本。但是現(xiàn)代編譯器都足夠聰明了,可以很好的處理好多行語(yǔ)句。很多語(yǔ)言都不需要明確使用分號(hào)結(jié)尾如:Go、Scala、Ruby、Python、Swift、Groovy 等等。
雖然 JavaScript 是 C-like 語(yǔ)言,但它是有別于 C、Java 的,在 JavaScript 中分號(hào)也是可選的,它自動(dòng)分號(hào)插入機(jī)制 Auto Semicolon Insertion (ASI)。
JavaScript 自動(dòng)分號(hào)插入機(jī)制
JavaScript 有著自動(dòng)分號(hào)插入的機(jī)制(Automatic Semicolon Insertion),簡(jiǎn)稱 ASI。在ECMA-262 - Automatic Semicolon Insertion中有關(guān) Automatic Semicolon Insertion 的明確說(shuō)明:
從左到右解析程序,當(dāng)遇到一個(gè)不符合任何文法產(chǎn)生式的 token(offending token),那么只要滿足下面條件之一就在違規(guī) token 前面自動(dòng)插入分號(hào)。
- 至少一個(gè)換行符(LineTerminator)分割了違規(guī) token 和前一個(gè) token。
- 違規(guī) token 是 }。
從左到右解析程序,tokens 輸入流已經(jīng)結(jié)束,當(dāng)解析器無(wú)法將輸入 token 流解析成單個(gè)完整 ECMAScript 程序 ,那么就在輸入流的結(jié)束位置自動(dòng)插入分號(hào)。
從左到右解析程序,遇到一個(gè)某些文法產(chǎn)生式允許的 token,但是它是受限操作(Restricted Productions),當(dāng)至少一個(gè)換行符分割了受限的 token 和前一個(gè) token,那么就在受限 token 前面自動(dòng)插入分號(hào)。
然而,上述規(guī)則有一個(gè)附加的優(yōu)先條件:如果插入分號(hào)后解析結(jié)果是空語(yǔ)句,或如果插入分號(hào)后它成為 for 語(yǔ)句頭部的兩個(gè)分號(hào)之一,那么不會(huì)自動(dòng)插入分號(hào)。
注:以上說(shuō)明翻譯較為別扭可以多讀幾遍或閱讀英文原文 ECMA-262 - Automatic Semicolon Insertion
分號(hào)自動(dòng)插入的情況
簡(jiǎn)要?dú)w納下,自動(dòng)分號(hào)插入以換行為基礎(chǔ),解析器會(huì)盡量將新行并入當(dāng)前行,當(dāng)且僅當(dāng)符合 ASI 規(guī)則時(shí)才會(huì)將新行視為獨(dú)立的語(yǔ)句
主要有以下自動(dòng)插入規(guī)則:
- 當(dāng)新的一行并入當(dāng)前行將構(gòu)成非法語(yǔ)句不能正確解析時(shí),將自動(dòng)插入分號(hào)
- 當(dāng)新行以}開頭時(shí),即代碼塊的結(jié)束位置,將自動(dòng)插入分號(hào)
- 當(dāng)以return語(yǔ)句結(jié)束時(shí), 在行末自動(dòng)插入分號(hào)
- 當(dāng)以break語(yǔ)句結(jié)束時(shí), 在行末自動(dòng)插入分號(hào)
- 當(dāng)以throw語(yǔ)句結(jié)束時(shí),在行末自動(dòng)插入分號(hào)
- 當(dāng)以continue語(yǔ)句結(jié)束時(shí), 在行末自動(dòng)插入分號(hào)
- 當(dāng)以 ES6 的 yield 語(yǔ)句結(jié)尾時(shí),在行末自動(dòng)插入分號(hào)
- ++、-- 后綴表達(dá)式作為新行的開始,在行首自動(dòng)插入分號(hào)
- 源代碼文件末尾自動(dòng)插入號(hào)
如上所示,如果沒(méi)加分號(hào),運(yùn)行這段代碼這段代碼將報(bào)錯(cuò)。
不能省略分號(hào)的情況
通常,如果語(yǔ)句以(、[、 /、+、-開頭時(shí),就有可能被解釋為上一行語(yǔ)句的一部分。實(shí)際中以/、+、-開頭的語(yǔ)句很少。但是以(、[開頭的語(yǔ)句則很常見(jiàn),通常我可以在行首防御性的加上分號(hào)。
前面,我們了解分號(hào)的自動(dòng)插入,現(xiàn)在我們來(lái)看一些示例
let hey = 'hey' ['liu','liuxing'].forEach(console.log)
思考一秒種上面的結(jié)果是什么?運(yùn)行這段代碼會(huì)拋出
Uncaught TypeError: Cannot read property 'forEach' of undefined
基于規(guī)則 1 上面代碼將會(huì)被解析成如下代碼
let hey = 'hey'['liu','liuxing'].forEach(console.log)
可以看出,使用[開頭的語(yǔ)句,前面沒(méi)有分號(hào),很可能導(dǎo)致出錯(cuò)。
再來(lái)看一個(gè)(開頭的語(yǔ)句的示例代碼
const a = 1 const b = 2 const c = a + b (a + b).toString()
你會(huì)以為上面的代碼結(jié)果是“3”嗎?但是實(shí)際上它會(huì)拋出錯(cuò)誤b is not a function,因?yàn)楦鶕?jù) ASI 規(guī)則,它會(huì)被解析成如下代碼:
const a = 1;const b = 2;const c = a + b(a + b).toString()
我們就不一一介紹/, +, - 作為語(yǔ)句開頭的情況了,這種情況比較少,大家可以自己試試。只需要記住語(yǔ)句以(、[、 /、+、-開頭時(shí),語(yǔ)句前需要加上分號(hào)即可!
下面再在看看使用return的情況,
(() => { return { name: 'Liu Xing' } })()
你的期待值是不是返回一個(gè)帶有 name 的對(duì)象,但是它卻返回了undefined。這是 ASI 自動(dòng)在return給加上了分號(hào)。在這兒就得正確的換行以確保代碼正確運(yùn)行。我們可以看出除了正確的的分號(hào),我們還需要正確合理的換行來(lái)使代碼結(jié)構(gòu)更為清晰。
總結(jié)
我們了解了 JavaScript 的分號(hào)自動(dòng)插入機(jī)制,知道了 JavaScript 什么時(shí)候會(huì)自動(dòng)加入分號(hào),在(、[、 /、+、-開頭時(shí)需要我們準(zhǔn)確的加上分號(hào)。Automatic Semicolon Insertion 機(jī)制為我們提供了兩種選擇,加還是加分號(hào)?完全看你或你的團(tuán)隊(duì)的喜好了,現(xiàn)在我們也有prettier、Eslint 等工具來(lái)自動(dòng)統(tǒng)一風(fēng)格。
到此這篇關(guān)于JavaScript中分號(hào)的文章就介紹到這了,更多相關(guān)JavaScript分號(hào)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS正則驗(yàn)證多個(gè)郵箱完整實(shí)例【郵箱用分號(hào)隔開】
- 淺談javascript的分號(hào)的使用
- JavaScript 自動(dòng)分號(hào)插入(JavaScript synat:auto semicolon insertion)
- 關(guān)于JavaScript語(yǔ)句后面的分號(hào)問(wèn)題
- JS 分號(hào)引起的一段調(diào)試問(wèn)題
- js中關(guān)于一個(gè)分號(hào)的崩潰示例
- javascript 分號(hào)總結(jié)及詳細(xì)介紹
- 淺析Javascript的自動(dòng)分號(hào)插入(ASI)機(jī)制
- 如何防止JavaScript自動(dòng)插入分號(hào)
- JavaScript中的分號(hào)插入機(jī)制詳細(xì)介紹
相關(guān)文章
JavaScript常用數(shù)組元素搜索或過(guò)濾的四種方法詳解
這篇文章主要介紹了JavaScript常用數(shù)組元素搜索或過(guò)濾的四種方法,每種方式通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08詳談innerHTML innerText的使用和區(qū)別
下面小編就為大家?guī)?lái)一篇詳談innerHTML innerText的使用和區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08全面了解addEventListener和on的區(qū)別
下面小編就為大家?guī)?lái)一篇全面了解addEventListener和on的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07用JS將搜索的關(guān)鍵字高亮顯示實(shí)現(xiàn)代碼
這篇文章介紹了JS將搜索的關(guān)鍵字高亮顯示實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-11-11js金額千分位的6種實(shí)現(xiàn)方法實(shí)例
在前端開發(fā)中經(jīng)常會(huì)遇到這樣一種需求,使用Javascript格式化數(shù)字進(jìn)行輸出,下面這篇文章主要給大家介紹了關(guān)于js金額千分位的6種實(shí)現(xiàn)方法,需要的朋友可以參考下2022-03-03javascript + jquery實(shí)現(xiàn)定時(shí)修改文章標(biāo)題
用javascript+jquery寫的一個(gè)定時(shí)器,定時(shí)修改文章標(biāo)題,需要的朋友可以參考下2014-03-03使用setTimeout實(shí)現(xiàn)SetInterval原理解析
這篇文章主要為大家介紹了使用setTimeout實(shí)現(xiàn)SetInterval原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10