程序語言的編碼風格對於一個長期維護的軟件很是重要,特別是在團隊協做中。若是一個團隊使用統一規範的編碼分風格,能夠提升團隊的協做水平和工做效率。編程風格指南的核心是基本的格式化規則,這些規則決定了如何編寫高水準的代碼。本指南來自於《編寫可維護的JavaScript》這本書,基於"Java語言編碼規範"和Crockford的JavaScript編程規範,還有Nicbolas的一些我的經驗和喜愛。寫做本文旨在加深本身印象,也爲了更多人的瞭解到JS編碼風格,提升本身的編碼質量。想了解更多的內容請閱讀《編寫可維護的JavaScript》。算法
每一行的層級由4個空格組成,避免使用Tab進行縮進。express
1 // 好的寫法 2 if (true) { 3 doSomeThing(); 4 }
每行長度不該超過80個字符。若是一行超過80個字符,應當在一個運算符後換行。下一行應當增長兩級縮進(8個字符)。編程
1 // 好的寫法 2 doSomeThing(argument1, argument2, aegument3, argument4, 3 argument5); 4 5 // 很差的寫法:第二行只有4個空格的縮進 6 doSomeThing(argument1, argument2, aegument3, argument4, 7 argument5);
字符串應當始終使用雙引號且保持一行,避免在字符串中使用斜線另起一行。瀏覽器
數字應當使用十進制整數,科學計算法表示整數,十六進制整數,或者十進制浮點小數,小數先後應當至少保留一位數字。避免使用八進制直接量。安全
特殊值null除了下述狀況下應當避免使用。函數
避免使用特殊值undefined。判斷一個變量是否認義應當使用typeof操做符。this
二元預算符先後必須使用一個空格來保持表達式的整潔。操做符包括賦值運算符和邏輯運算符。編碼
1 // 好的寫法 2 for (var i = 0; i < count; i++) { 3 process(i); 4 } 5 6 // 很差的寫法:丟失了空格 7 for (var i=0; i<count; i++) { 8 process(i); 9 }
當使用括號時,緊接左括號以後和緊接右括號以前不該該有空格。spa
1 // 好的寫法 2 for (var i = 0; i < count; i++) { 3 process(i); 4 } 5 6 // 很差的寫法:參數兩邊有額外的空格 7 for (var i = 0; i < count; i++) { 8 process( i ); 9 }
對象直接量應當有以下格式。code
1 // 好的寫法 2 var object = { 3 4 key1: value1, 5 key2: value2, 6 7 func: function() { 8 // doSomeThing 9 }, 10 11 key3: value3 12 }; 13 14 // 很差的寫法:不恰當的縮進 15 var object = { 16 key1: value1, 17 key2: value2 18 }; 19 20 // 很差的寫法:函數體周圍缺乏空行 21 var object = { 22 23 key1: value1, 24 key2: value2, 25 func: function() { 26 // doSomeThing 27 }, 28 key3: value3 29 };
當對象字面量做爲函數參數時,若是值是變量,起始花括號應當同函數名在同一行。全部其他先前列出的規則一樣適用。
1 // 好的寫法 2 doSomeThing({ 3 key1: value1, 4 key2: value2 5 }); 6 // 很差的寫法:全部代碼在一行上 7 doSomeThing({ key1: value1, key2: value2 });
使用簡潔明瞭註釋有助於他人理解你的代碼。以下狀況應當使用註釋。
單行註釋應當用來講明一行代碼或者一組相關的代碼。單行註釋可能有三種使用方式。
1 // 好的寫法 2 if (condition) { 3 4 // 若是代碼執行到這裏,則代表經過了全部安全檢查 5 allowed(); 6 } 7 8 // 很差的寫法:註釋以前沒有空行 9 if (condition) { 10 // 若是代碼執行到這裏,則代表經過了全部安全檢查 11 allowed(); 12 } 13 14 // 很差的寫法:錯誤的縮進 15 if (condition) { 16 17 // 若是代碼執行到這裏,則代表經過了全部安全檢查 18 allowed(); 19 } 20 21 // 很差的寫法:應當使用多行註釋 22 // 這段代碼進行**判斷 23 // 而後執行 24 if (condition) { 25 26 // 若是代碼執行到這裏,則代表經過了全部安全檢查 27 allowed(); 28 } 29 30 // 好的寫法:在行尾註釋時,代碼結尾和註釋間應保留一個空格 31 if (condition) { 32 33 // 若是代碼執行到這裏,則代表經過了全部安全檢查 34 allowed(); // 執行**函數 35 } 36 37 // 很差的寫法:代碼和註釋間沒有足夠的空格 38 if (condition) { 39 40 // 若是代碼執行到這裏,則代表經過了全部安全檢查 41 allowed();// 執行**函數 42 } 43 44 // 好的寫法:在註釋掉一個代碼塊時,應聯繫使用單行註釋,多行註釋不該當使用在此種狀況下。 45 // if (condition) { 46 // allowed();//執行**函數 47 // }
多行註釋應當在代碼須要更多文字去解釋的時候使用。每一個多行註釋都至少有以下三行:
多行註釋的首行應當保持同它描述代碼的相同層次的縮進。後續的每行應當有一樣層次的縮進並附加一個空格(爲了適當保持*字符的對齊)。每個多行代碼以前應當預留一個空行。
1 // 好的寫法、 2 if (condition) { 3 4 /* 5 * 若是代碼執行到這裏 6 * 說明經過了全部的安全檢測 7 */ 8 allowed(); 9 }
註釋有時候也能夠用來給一段代碼聲明額外的信息。這些聲明的格式以單個單詞打頭並緊跟一個冒號。可使用的聲明以下。
TODO:說明代碼還未完成。應當包含下一步要作的事情。
HACK:代表代碼實現走了一個捷徑。應當包含爲什麼使用hack的緣由。這也可能代表該問題可能會有更好的解決辦法。
XXX:說明代碼是有問題的並應當儘快修復。
FIXME:說明代碼是有問題的並應儘快修復。重要性略次於XXX。
REVIEW:說明代碼在任何可能的改動都須要評審。
這些聲明可能在一行或者多行註釋中使用,而且應當遵循同通常註釋類型相同的格式規則。
變量和函數在命名時應當當心。命名應緊限於數字字母字符,某些狀況下可使用下劃線(_)。最好不要在任何命名中使用美圓符號($)或者反斜槓(\)。
變量命名應當採用駝峯命名格式,首字母小寫,每一個單詞首字母大寫。變量名的第一個單詞應當是一個名詞(而非動詞)以免同函數混淆。不要在變量名中使用下劃線。
1 // 好的寫法 2 var accountNumber = "test001"; 3 4 // 很差的寫法:大寫字母開頭 5 var AccountNumber = "test001"; 6 7 // 很差的寫法:動詞開頭 8 var getAccountNumber = "test001"; 9 10 // 很差的寫法:使用下劃線 11 var account_number = "test001";
函數名也應當採用駝峯命名格式。函數名的第一個單詞應當是動詞(而非名詞)來避免同變量混淆。函數名中最好不要使用下劃線。
1 // 好的寫法 2 function doSomething() { 3 // code 4 } 5 6 // 很差的寫法:大寫字母開頭 7 function DoSomething() { 8 // code 9 } 10 11 // 很差的寫法:名詞開頭 12 function something() { 13 // code 14 } 15 16 // 很差的寫法:使用下劃線 17 function do_something() { 18 // code 19 }
構造函數--經過new運算符建立新對象的函數--也應當以駝峯格式命名而且首字符大寫。構造函數名稱應當以非動詞開頭,由於new表明着建立一個對象實例的操做。
1 // 好的寫法 2 function MyObject() { 3 // code 4 } 5 6 // 很差的寫法:小寫字母開頭 7 function myObject() { 8 // code 9 } 10 11 // 很差的寫法:使用下劃線 12 function my_object() { 13 // code 14 } 15 16 // 很差的寫法:動詞開頭 17 function getMyObject() { 18 // code 19 }
常量(值不會被改變的變量)的命名應當是全部大寫字母,不一樣單詞之間單個下劃線隔開。
1 // 好的寫法 2 var TOTAL_COUNT = 10; 3 4 // 很差的寫法:駝峯形式 5 var totalCount = 10; 6 7 // 很差的寫法:混合形式 8 var total_COUNT = 10;
對象的屬性同變量的命名規則相同。對象的方法同函數的命名規則相同。若是屬性或者方法是私有的,應當在以前加上一個下劃線。
1 // 好的寫法 2 var object = { 3 _count: 10,4 5 _getCount: function() { 6 return this._count; 7 } 8 }
全部的變量在使用前都應當事先定義。變量定義應當放在函數開頭,使用一個var表達式每行一個變量。除了首行,全部行都應當多一層縮進以使變量名可以垂直方向對齊。變量定義時應當初始化,而且賦值操做符應當保持一致的縮進。初始化的變量應當在未初始化變量以前。
1 // 好的寫法 2 var count = 10, 3 name = "jeri", 4 found = false, 5 empty;
函數應當在使用前提早定義。一個不是做爲方法的函數(也就是說沒有做爲一個對象的屬性)應當使用函數定義的格式(不是函數表達式和Function構造器格式)。函數名和開始圓括號之間不該當有空格。結束的圓括號和右邊的花括號之間應當留一個空格。右側的花括號應當同function關鍵字保持同一行。開始和結束括號之間不該該有空格。參數名之間應當在逗號以後保留一個空格。函數體應當保持一級縮進。
1 // 好的寫法 2 function outer() { 3 var count = 10, 4 name = "jeri", 5 found = false, 6 empty; 7 function inner() { 8 // code 9 } 10 // 調用inner()的代碼 11 }
匿名函數可能做爲方法賦值給對象,或者做爲其餘函數的參數。function關鍵字同開始括號之間不該有空格。
1 // 好的寫法 2 object.method = function() { 3 // code 4 }; 5 6 // 很差的寫法:不正確的空格 7 object.method = function () { 8 // code 9 };
當即被調用的函數應當在函數調用的外層用園括號包裹。
1 // 好的方法 2 var value = (function() { 3 4 // 函數體 5 6 return { 7 message:"hi" 8 } 9 }());
嚴格模式應當僅限在函數內部使用,千萬不要在全局使用。
1 // 很差的寫法:全局使用嚴格模式 2 "use strict"; 3 4 function doSomething() { 5 // code 6 } 7 8 // 好的寫法 9 function doSomething() { 10 "use strict"; 11 12 // code 13 }
給變量賦值時,若是右側是含有比較語句的表達式,須要用圓括號包裹。
1 // 好的寫法 2 var flag = (i < count); 3 4 // 很差的寫法:遺漏圓括號 5 var flag = i < count;
使用===(嚴格相等)和!==(嚴格不相等)代替==(相等)和!=(不等)來避免弱類型轉換錯誤。
1 // 好的寫法 2 var same = (a === b); 3 4 // 好的寫法 5 var same = (a == b);
三元運算符應當僅僅用在條件賦值語句中,而不要做爲if語句的替代品。
1 // 好的寫法 2 var value = condition ? value1 : value2; 3 4 // 很差的寫法:沒有賦值,應當使用if表達式 5 condition ? doSomething() : doSomethingElse;
每一行最多隻包含一條語句。全部簡單的語句都應該以分號(;)結束。
1 // 好的寫法 2 count++; 3 a = b; 4 5 // 很差的寫法:多個表達式寫在一行 6 count++; a = b;
返回語句當返回一個值的時候不該當使用圓括號包裹,除非在某些狀況下這麼作可讓返回值更容易理解。例如:
1 return; 2 3 return collection.size(); 4 5 return (size > 0 ? size : defaultSize);
複合語句是大括號括起來的語句列表。
if 語句應當是下面的格式。
1 if (condition) { 2 statements 3 } 4 5 if (condition) { 6 statements 7 } else { 8 statements 9 } 10 11 if (condition) { 12 statements 13 } else if (condition) { 14 statements 15 } else { 16 statements 17 }
毫不容許在if語句中省略花括號。
1 // 好的寫法 2 if (condition) { 3 doSomething(); 4 } 5 6 // 很差的寫法:不恰當的空格 7 if (condition){ 8 doSomething(); 9 } 10 11 // 很差的寫法:全部代碼都在一行 12 if (condition) { doSomething(); } 13 14 // 很差的寫法:全部代碼都在一行且沒有花括號 15 if (condition) doSomething();
for類型的語句應當是下面的格式。
1 for (initialization; condition; update) { 2 statements 3 } 4 5 for (variable in object) { 6 statements 7 }
for語句的初始化部分不該當有變量聲明。
1 // 好的方法 2 var i, 3 len; 4 5 for (i=0, len=0; i < len; i++) { 6 // code 7 } 8 9 // 很差的寫法:初始化時候聲明變量 10 for (var i=0, len=0; i < len; i++) { 11 // code 12 } 13 14 // 很差的寫法:初始化時候聲明變量 15 for (var prop in object) { 16 // code 17 }
當使用for-in語句時,記得使用hasOwnProperty()進行雙重檢查來過濾對象的成員。
while 類的語句應當是下面的格式。
1 while (condition) { 2 statements 3 }
do 類的語句應當是下面的格式。
1 do { 2 statements 3 } while (condition);
switch 類的語句應當是以下格式。
1 switch (expression) { 2 case expression: 3 statements 4 5 default: 6 statements 7 }
switch下的第一個case都應當保持一個縮進。除第一個以外包括default在內的每個case都應當在以前保持一個空行。
每一組語句(除了default)都應當以break、return、throw結尾,或者用一行註釋表示跳過。
1 // 好的寫法 2 switch (value) { 3 case 1: 4 /* falls through */ 5 6 case 2: 7 doSomething(); 8 break; 9 10 case 3: 11 return true; 12 13 default: 14 throw new Error("Some error"); 15 }
若是一個switch語句不包含default狀況,應當用一行註釋代替。
1 // 好的寫法 2 switch (value) { 3 case 1: 4 /* falls through */ 5 6 case 2: 7 doSomething(); 8 break; 9 10 case 3: 11 return true; 12 13 default: 14 // 沒有default 15 }
try類的語句應當格式以下。
1 try { 2 statements 3 } catch (variable) { 4 statements 5 } 6 7 try { 8 statements 9 } catch (variable) { 10 statements 11 } finally { 12 statements 13 }
在邏輯相關的代碼之間添加空行代碼能夠提升代碼的可讀性。
兩行空行僅限於在以下狀況下使用:
單行空行僅限在以下狀況中使用。
空格應當在以下的狀況下使用。
上述指南並非在開發過程當中必須徹底遵照的,咱們能夠只汲取其中的一部分來改善本身的編碼風格,讓本身的代碼易讀、可維護。關於編碼風格,每一個團隊都有本身的特點,只要保持團隊一致性,能夠高效的開發就OK了。有些規則也並非咱們必須一成不變地遵照的,好比在縮進方面,咱們使用Tab鍵不少時候更加地便捷,可是咱們不能保證在任何環境下Tab都表明4個空格,爲了在縮進方面保持一致性,若是使用Tab鍵那麼在整個過程當中都要使用;還有關於""和‘’的使用,咱們也沒必要都使用"",使用''也是能夠的,只要保持一致的風格就能夠了。還有不少其餘相似的風格問題,全憑我的選擇。
沒有絕對的準則,只有適不適合。