JavaScript語句末尾應該加分號麼?

cnnbull發表於2021-09-09

關於JavaScript中行尾分號問題, 由來爭議已久.

其中有大師Douglas Crockford以及JSLint的建議一定新增方位分號, 也有很多其他大牛(諸如Zepto的作者)加入了 無分號黨 .

其中孰是孰非也是仁者見仁, 智者見智了.

這篇文章下面會為大家介紹 無分號黨 中代表人物"Mislav Marohnić"對於此問題的闡述.

JavaScript是一門指令碼語言, 它的程式碼段結束符是可選的.

但是, 總是有一群人在質疑這個特性, 這也導致了, 大部分開發人員都會 , "僅僅為了安全".

安全從何而來? 我一直在搜尋開發人員強制新增分號的原因. 下面是我找到的一些原因.


規範含義很模糊並且JavaScript實現存在差異

, 但是要有一個很明確的理解有些困難的.

至於JavaScript的實現中關於這些規則的差異, 好吧, 我還沒有找到過.

當我向開發人員諮詢或查詢討論資料時, 通常他們的回答都是"瀏覽器確實崩潰過, 但是我忘了具體情況", 當然, 他們從未記起過.

我總是編寫"無分號程式碼", 按照我的經驗, 沒有發現任何一個JavaScript直譯器不能處理這些程式碼.


沒有分號, 無法壓縮JavaScript 程式碼

縮減JavaScript原始碼檔案大小包括三種級別: 壓縮(例如gzip), 簡化(比如去除不必要的空格及註釋), 混淆(改變程式碼, 縮短變數和函式名).

壓縮(Compression)是最簡單的, 只需要一次性的服務端配置, 而不需要開發人員額外的工作以及無需程式碼. 有一段時間IE6是不能處理這種方式的, 但是如果我記得沒錯, 多年前已經打了補丁並推送了Windows更新, 如今已經沒人在意這點了.

簡化(Minification)與混淆(Obfuscation)會改變程式碼. 有很多的工具都標榜著"對於JavaScript檔案, 嘗試把它們變的更小, 但不會影響功能性". 對於這些工具, 我是有些牴觸的, 因為如果不使用特定的程式碼格式, 比如新增分號, 它們就會破壞我的程式碼. 對於社群強制要求特定程式碼格式的要求, 其實我是ok的, 但不包括這些工具的要求.

設想一段在所有目標JavaScript實現(主流瀏覽器及一些服務端實現)中可用的程式碼, 如果壓縮工具破壞了我的這段程式碼, 我會很憂桑的認為那是工具本身是錯的. 如果工具編輯了JavaScript程式碼, 那麼它最好像一個真正的直譯器來理解程式碼.

對於壓縮這一話題, 讓我們做一個顯示的檢查. 我獲取了 jQuery 的原始碼並 , 然後在程式碼上執行. 結果檔案大小為 76,673位元組 . 而 jquery.min.js 的大小為 76,674位元組 , 僅僅多了一個位元組. 正如所見, 幾乎沒有任何變化, 當然, 測試用例也像之前一樣透過了.

為什麼會這樣? 好吧, 考慮以下程式碼:

var a=1var b=2var c=3

這段程式碼大小為24個位元組. 標記上分號, 執行壓縮器:

var a=1;var b=2;var c=3;

依然是24個位元組. 因此, 新增分號並去除換行符沒有節省任何空間. 大多數節省的空間不是透過刪除換行符體現的 - 而是透過刪除程式碼註釋和行首縮排實現的.

更新:很多人指出他們的壓縮器重寫了表示式, 比如 var a=1,b=2,c=3 . 我知道一些工具會這樣處理, 但是此部分的觀點只是探尋分號與空格的關係. 如果壓縮器有著優秀的表示式重寫能力(比如:閉包編譯器), 那麼意味著它也可以自動插入分號.

還有一些人推薦強制在程式碼塊外使用花括號, 即使只有一行程式碼:

// beforeif(condition) stuff()// afterif(condition){
    stuff()}// after minificationif(condition){stuff()}

即使壓縮後, 強制新增花括號也會至少增加一個位元組的空間開銷. 我不確定這有什麼好處 - 對於空間及可讀性都沒有任何益處.

下面列舉出了一些其他空格敏感的語言:

  • Ruby — 在語句中包含運算子會影響空間並且方法呼叫會破壞程式碼.

  • Python — 呃.

  • HTML — 可以參考 

當然, 伺服器端程式碼沒有必要進行壓縮. 為以下論點我做了這個列表: 空格可以並且總是可以, 部分(標記)語言. 這並不是一件壞事.


優秀的編碼習慣

還聽到過如下觀點:

  • 為了保證程式碼一致性, 保留分號是好的

  • 會編譯報錯

這是另一種表達"其他人都這麼做"的方式, 也常常被線上討論時理屈詞窮的人們用到.

對於 JSLint 我的建議是: 不要使用它. 為什麼要使用它? 如果你深信它會幫助你減少程式碼中的BUG, 有這樣一個觀點: 只有能發現並解決軟體BUG的人, 沒有那樣的工具. 因此將工具丟到一邊, 讓更多的人來閱讀你的程式碼吧.

Douglas Crockford說過"使用4個空格縮排", 然而大多數流行的JavaScript庫都被設定為 tabs 或 2個空格 . 社群內的不同專案也是存在差異的, 它們就應該是那樣. 正如我之前所說: 讓人們和你本身形成你的程式碼風格, 而不是個人或某個工具.

你或許注意到在這篇文章中, 我並沒有告訴你們應該堅持"無空格". 我只是闡述了可以這麼做的具體證據. 但是選擇權還在你們那.

對於程式碼風格, 它們的存在是為了提升開發人員對於程式碼的可讀性與易理解性. 請深入思考是否分號提示了你程式碼的可讀性. 對於可讀性提示最大的因素應該是:空格縮排, 分隔程式碼塊的空行, 拉長表示式的空格, 以及良好的變數及方法的命名方式. 閱讀一些混淆過的程式碼, 其中包含了分號. 但這對於可讀性有任何幫助麼? 沒有, 而恰恰是大量的空格與最初的變數名起到了真正的作用.


分號插入在返回程式碼內被吞了

當我搜尋"JavaScript semicolon insertion"時, 最多的描述是這樣的:

function add() {
    var a = 1, b = 2
    return
    a + b}

當你絞盡腦汁想明白為什麼他們要把 return 程式碼另起一行時, 我們可以繼續來看這段程式碼是如何解析的:

return;a + b;

唉, 這個函式沒有返回我們需要的"和"! 但是你猜怎麼著? 這個問題不是靠在 return 表示式末尾新增一個分號(也就是, a+b後面)來解決的, 而是透過刪除 return 後面的換行符解決的:

return a + b

這樣的內容真的是很離譜, 這些人建議他們的讀者透過新增分號來避免這樣的問題. 呃, 好吧, 只是幫助不到到這個特定的例子而已. 我們只需要更好的理解這門語言是如何解析的.


唯一真正的缺陷

這是"無分號"情況下唯一需要注意的地方:

// careful: will breaka = b + c(d + e).print()

這段程式碼會被執行為:

a = b + c(d + e).print();

這個例子是取自於 , 但我也在自己的程式中使用這個模型模式執行了若干次.

簡單的解決方案: 當一行以圓括號開始時, 給它預置一個分號.

;(d + e).print()

這可能不是很優雅, 但是起到了作用. :

如果選擇在可能的地方忽視分號, 我的建議是: 在任何程式碼塊中, 只要以開括號( [] )或任意數學運算子(+ - * /)開頭, 在符號之前應立即插入一個分號.

將這條建議視為一個規則, 你會受益良多.

注:本文為譯文,原文出處 

原文連結:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2524/viewspace-2805625/,如需轉載,請註明出處,否則將追究法律責任。

相關文章