我們的程式碼必須盡可能乾淨且易於閱讀。
這實際上是編程的藝術——接受複雜的任務並以正確且人類可讀的方式對其進行編碼。良好的程式碼風格對此有很大幫助。
這是一份包含一些建議規則的備忘單(有關更多詳細信息,請參閱下文):
現在讓我們詳細討論一下它們的規則和原因。
沒有「你必須」的規則
這裡沒有什麼是一成不變的。這些是風格偏好,而不是宗教教條。
在大多數 JavaScript 專案中,大括號以「埃及」風格編寫,左大括號與對應的關鍵字位於同一行,而不是新行。左括號前還應該有一個空格,如下圖:
如果(條件){ // 這樣做 // ...還有那個 // ...還有那個 }
單行構造,例如if (condition) doSomething()
,是一種重要的邊緣情況。我們到底該使用牙套嗎?
以下是帶註釋的變體,以便您可以自己判斷它們的可讀性:
?初學者有時會這樣做。壞的!不需要花括號:
if (n < 0) {alert(`不支援 Power ${n}`);}
?不帶大括號拆分為單獨的行。千萬不要這樣做,新增行時很容易出錯:
如果(n<0) alert(`不支援電源 ${n}`);
?一行不帶大括號 - 如果很短,可以接受:
if (n < 0)alert(`不支援 Power ${n}`);
?最佳變體:
如果(n<0){ alert(`不支援電源 ${n}`); }
對於非常簡短的程式碼,允許一行,例如if (cond) return null
。但程式碼區塊(最後一個變體)通常更具可讀性。
沒有人喜歡閱讀一長串水平代碼。最好的做法是將它們分開。
例如:
// 反引號`允許將字串分成多行 讓str=` ECMA International 的 TC39 是一群 JavaScript 開發人員, 實施者、學者等與社區合作 維護和發展 JavaScript 的定義。 `;
並且,對於if
語句:
如果 ( id === 123 && 月相 === '漸虧凸月' && zodiacSign === '天秤座' ){ 讓TheSorceryBegin(); }
最大線路長度應在團隊層級達成協議。通常為 80 或 120 個字元。
縮排有兩種類型:
水平縮排:2 或 4 個空格。
使用 2 個或 4 個空格或水平製表符( Tab鍵)進行水平縮排。選擇哪一場是古老的聖戰。如今,空間更常見。
與製表符相比,空格的優點之一是,與製表符相比,空格允許更靈活的縮排配置。
例如,我們可以將參數與左括號對齊,如下所示:
顯示(參數, aligned, // 左側填滿 5 個空格 一, 後, 其他 ){ // ... }
垂直縮排:用於將程式碼分割成邏輯區塊的空白行。
即使是單一功能通常也可以分為多個邏輯區塊。在下面的例子中,變數的初始化、主循環和返回結果被垂直分割:
函數 pow(x, n) { 讓結果= 1; // <-- for (設 i = 0; i < n; i++) { 結果*=x; } // <-- 返回結果; }
插入額外的換行符,有助於使程式碼更具可讀性。沒有垂直縮排的程式碼不應超過九行。
每個語句後面都應該有一個分號,即使它可能被跳過。
在某些語言中,分號確實是可選的,但很少使用。但在 JavaScript 中,有時換行符號不會被解釋為分號,導致程式碼容易出錯。有關詳細信息,請參閱代碼結構一章。
如果您是經驗豐富的 JavaScript 程式設計師,您可以選擇像 StandardJS 這樣的無分號程式碼風格。否則,最好使用分號以避免可能的陷阱。大多數開發人員都使用分號。
盡量避免嵌套程式碼太深。
例如,在迴圈中,有時使用continue
指令來避免額外的巢狀是個好主意。
例如,不要像這樣加入嵌套的if
條件:
for (設 i = 0; i < 10; i++) { 如果(條件){ ... // <- 多一層嵌套 } }
我們可以寫:
for (設 i = 0; i < 10; i++) { if (!cond) 繼續; ... // <- 沒有額外的巢狀級別 }
使用if/else
和return
可以完成類似的事情。
例如,下面的兩個構造是相同的。
選項 1:
函數 pow(x, n) { 如果(n<0){ Alert("不支援負數 'n'"); } 別的 { 讓結果= 1; for (設 i = 0; i < n; i++) { 結果*=x; } 返回結果; } }
選項2:
函數 pow(x, n) { 如果(n<0){ Alert("不支援負數 'n'"); 返回; } 讓結果= 1; for (設 i = 0; i < n; i++) { 結果*=x; } 返回結果; }
第二個更具可讀性,因為n < 0
的「特殊情況」已儘早處理。檢查完成後,我們可以繼續「主」代碼流,而不需要額外的嵌套。
如果您正在編寫多個「輔助」函數以及使用它們的程式碼,則可以透過三種方式來組織這些函數。
在使用函數的程式碼上方宣告函數:
// 函數宣告 函數創建元素() { … } 函數 setHandler(elem) { … } 函數 walkAround() { … } // 使用它們的程式碼 讓 elem = createElement(); setHandler(elem); 走動();
先編碼,再函數
// 使用函數的程式碼 讓 elem = createElement(); setHandler(elem); 走動(); // --- 輔助函數 --- 函數創建元素() { … } 函數 setHandler(elem) { … } 函數 walkAround() { … }
混合:函數在第一次使用的地方聲明。
大多數時候,第二種變體是首選。
那是因為在閱讀程式碼時,我們首先想知道它做了什麼。如果程式碼先行,那麼從一開始就很清楚。然後,也許我們根本不需要閱讀這些函數,特別是當它們的名稱描述了它們實際執行的操作時。
風格指南包含「如何寫」程式碼的一般規則,例如使用哪些引號、縮排多少空格、最大行長度等。
當團隊的所有成員使用相同的風格指南時,無論哪個團隊成員編寫程式碼,程式碼看起來都是統一的。
當然,團隊總是可以編寫自己的風格指南,但通常沒有必要。有許多現有指南可供選擇。
一些流行的選擇:
谷歌 JavaScript 風格指南
Airbnb JavaScript 風格指南
慣用語
標準JS
(還有更多)
如果您是新手開發人員,請從本章開頭的備忘單開始。然後您可以瀏覽其他風格指南以獲取更多想法並決定您最喜歡哪一個。
Linters 是可以自動檢查程式碼風格並提出改進建議的工具。
它們的優點在於,樣式檢查還可以發現一些錯誤,例如變數或函數名稱中的拼字錯誤。由於此功能,即使您不想堅持特定的“程式碼風格”,也建議使用 linter。
以下是一些著名的 linting 工具:
JSLint-最早的 linter 之一。
JSHint – 比 JSLint 更多的設定。
ESLint – 可能是最新的。
他們所有人都能勝任這項工作。作者使用ESLint。
大多數 linter 都與許多流行的編輯器整合:只需在編輯器中啟用插件並配置樣式即可。
例如,對於 ESLint,您應該執行以下操作:
安裝 Node.js。
使用指令npm install -g eslint
安裝 ESLint(npm 是一個 JavaScript 套件安裝程式)。
在 JavaScript 專案的根目錄(包含所有檔案的資料夾中)建立一個名為.eslintrc
的設定檔。
為您的編輯器安裝/啟用與 ESLint 整合的插件。大多數編輯都有一個。
以下是.eslintrc
檔的範例:
{ "extends": "eslint:推薦", 「環境」:{ 「瀏覽器」:正確, 「節點」:正確, 「es6」:正確 }, 「規則」:{ 「無控制台」:0, 「縮排」:2 } }
這裡指令"extends"
表示配置基於「eslint:recommished」設定集。之後,我們指定我們自己的。
也可以從網頁下載樣式規則集並擴展它們。有關安裝的更多詳細信息,請參閱 https://eslint.org/docs/user-guide/getting-started。
此外,某些 IDE 具有內建的 linting,這很方便,但不如 ESLint 那樣可自訂。
本章(以及引用的樣式指南)中所述的所有語法規則旨在提高程式碼的可讀性。所有這些都是有爭議的。
當我們考慮編寫“更好”的程式碼時,我們應該問自己的問題是:“是什麼使程式碼更具可讀性和更容易理解?”以及“什麼可以幫助我們避免錯誤?”這些是選擇和討論程式碼風格時要記住的主要事項。
閱讀流行的風格指南將使您能夠隨時了解有關程式碼風格趨勢和最佳實踐的最新想法。
重要性:4
下面的程式碼風格有什麼問題嗎?
函數 pow(x,n) { 讓結果=1; for(令 i=0;i<n;i++) {結果*=x;} 返回結果; } 讓 x=提示("x?",''), n=提示("n?",'') 如果(n<=0) { alert(`不支援Power ${n},請輸入大於零的整數`); } 別的 { 警報(戰力(x,n)) }
修復它。
您可以注意以下幾點:
function pow(x,n) // <- 參數之間沒有空格 { // <- 數字括號另起一行 讓結果=1; // <- = 之前或之後沒有空格 for(let i=0;i<n;i++) {result*=x;} // <- 沒有空格 // { ... } 的內容應該換行 返回結果; } let x=prompt("x?",''), n=prompt("n?",'') // <-- 技術上可行, // 但最好將其設為 2 行,而且不要有空格和缺失; if (n<=0) // <- 內部沒有空格 (n <= 0),上面應該有額外的一行 { // <- 數字括號另起一行 // 下面 - 長行可以分成多行以提高可讀性 alert(`不支援Power ${n},請輸入大於零的整數`); } else // <- 可以寫在一行上,如“} else {” { Alert(pow(x,n)) // 沒有空格且缺少 ; }
固定變體:
函數 pow(x, n) { 讓結果= 1; for (設 i = 0; i < n; i++) { 結果*=x; } 返回結果; } 讓 x = 提示("x?", ""); 讓 n = 提示("n?", ""); 如果(n <= 0){ 警報(`不支援電源 ${n}, 請輸入一個大於零的整數`); } 別的 { 警報(戰俘(x,n)); }