最近讀了一篇javascritpt的代碼相關的文章,感覺特別不錯,就翻譯成中文了,同時發表在簡書上,原文鏈接(http://javascript.crockford.com/code.html)
Javascript代碼規範
這部分講有關javascript的代碼規範及規則。
軟件的長期價值和它的代碼質量是成正比的。在軟件的聲明週期中,代碼可能會被很多人閱讀和修改。如果程序具有良好的結構及特性,那麼在修改過程會不那麼容易崩潰,良好的代碼規範可以增加程序的健壯性。
所有的javascript代碼都直接呈現在公衆的面前,我們需要注重它的質量和整潔性。
Javadcript文件
Javascript文件以.js命名
Javascrip代碼不應該嵌入html代碼中,除非是用於一次特定的會話,javascript代碼加入到html中會增加文件的大小消耗資源,並且不能通過緩存和壓縮的方式來減少消耗。
空行空格
在可能的情況下,這些規則與幾個世紀的文學風格的良好實踐是一致的。如果有強有力的證據表明有顯着的好處,那麼可以應該容忍與文學風格的偏差。
空行將代碼斷開爲具有邏輯聯繫的代碼段,來增加可讀性。
空行的使用場景如下:
1)在關鍵字跟着左括號的情況下,關鍵字與左括號之間應該存在空格,這樣可以很好的區分調用和那些非調用的情況,例如在if和while之後應在有空格
While (
2)調用函數時,函數名字和左括號之間不應該有空格。這樣可以很好的區分開關鍵字和函數調用的情況
3)在一元運算符和操作數之間不應該存在空格,除非一元操作符是一個單詞,例如typeof
4)每個二元運算符及其操作數應該通過一側的空格隔開,除了句點(.)、左中括號([)、左括號(()
5)每個逗號之後應該是一個空格或者是一個空行
6)在程序語句中,分號後面應該跟着空行
7)在流程控制語句中,分號應該跟着一個空格
每個語句開始前應該縮進對齊,最外層代碼應該和左邊緣對其,每次縮進增長4個單位,如果上一行的最後一個字符是(、[、{等符號,那麼它的閉合符號應該在新的一行的第一個字符位置。
由於三目運算表達式非常容易導致混淆,所以應該將問號(?)作爲一行的開頭,且縮進四個單位,對於冒號(:)應該重新開始一行,和上一行問號對齊。三目運算表達式的條件應該包含在括號中。
var integer = function (
value,
default_value
) {
value = resolve(value);
return (typeof value === "number")
? Math.floor(value)
: (typeof value === "string")
? value.charCodeAt(0)
: default_value;
};
如果句點(.)在一行的第一個位置,應該增加4個縮進。
避免一行語句太長,如果一條語句在一行之內看起來不是那麼合適,應該把它斷開爲多行。在左大括號({)左中括號([)左括號(()之後的語句,或是在逗號(,)、句號(.)、問號(?)、冒號(:)之前的語句最好是斷開。如果以上面方式斷開時不可行的,那就在操作符之後斷開,在下一行開始相對上一行開始增加8個縮進,那八個縮進不能影響正在遞增進行的全局縮進。
這些子句(case, catch, default, else, finally)不是順序語句,不應該像順序語句那樣縮進。
製表符和空格符不應該被混淆。我們應該選擇其中一個符號來做分割使用,來避免兩者混淆問題。個人偏好一個標準。無論是製表符還是空格都沒有提供極大的優勢,五年前製表符的優勢在於消耗更少的內存空間,但是摩爾定律消除了這一優勢,空格相對於製表符的優勢在於更清晰,所以經常使用空格,你可以在編輯的時候使用製表符,但是在提交的時候需要確保它被替換成空格。可能會在某一天,我們會得到一個通用的標準,使更好的選擇是空格。
註釋
註釋是很常用的,它讓以後讀代碼的人更好的理解你的代碼。應該認真的寫註釋,而且寫得很清晰,應該像那些非常好的註釋一樣。偶爾可以有一些幽默感,但是不應該包含沮喪和抱怨。保持註釋隨代碼修改而更新是很重要的。錯誤的註釋會使程序更加難理解。
註釋應該是有意義的,不應該爲那些顯而易見的代碼加上註釋,例如
i = 0; // Set i to zero.
不應該以此浪費讀者的時間。
變量聲明
所有變量在使用之前都應該被定義,雖然javascript並沒有強制要求,但是在使用之前聲明變量可以使變量更加的清楚,且更容易發現未被聲明的隱藏變量。不應該使用隱含的全局變量,應該儘可能的減少全局變量的使用。
最好對每個變量進行聲明和註釋,並且儘可能按照字典的順序排列。
var currentEntry; // currently selected table entry
var level; // indentation level
var size; // size of table
javascript變量沒有塊範圍,所以在塊中定義變量時可能會使那些對C相類似語言非常有經驗的人產生混淆。
函數聲明
所有都需要函數在使用之前被定義,內部函數應該遵循var語句形式。這樣可以很清楚的看出函數內部包含哪些變量。函數名字和函數參數列表的左括號之間沒有空格,函數參數列表的右括號和函數語句之前的大括號之間應該存在一個空格,函數內部語句應該縮進四個空格,函數的最後一個大括號應該和函數最開始聲明處對齊。
function outer(c, d) {
var e = c * d;
function inner(a, b) {
return (e * a) + b;
}
return inner(0, 1);
}
這對於javascript來說是一個很好的約定,在javascript中函數和對象自變量可以出現在任何的地方,上述約定可以使複雜的javascript代碼結構有很好的閱讀性。
function getElementsByClassName(className) {
var results = [];
walkTheDOM(document.body, function (node) {
var array; // array of class names
var ncn = node.className; // the node's classname
// If the node has a class name, then split it into a list of simple names.
// If any of them match the requested name, then append the node to the list of results.
if (ncn && ncn.split(" ").indexOf(className) >= 0) {
results.push(node);
}
});
return results;
}
If a function literal is anonymous, there should be one space between the word function and the ( left parenthesis. If the space is omitted, then it can appear that the function's name is function, which is an incorrect reading.
div.onclick = function (e) {
return false;
};
that = {
method: function () {
return this.datum;
},
datum: 0
};
如果是匿名函數,在function 和其後的左括號之間應該存在一個空格,如果空格被省略,那麼函數的名字可能會被錯認爲是function,這是一個不正確的讀法。
div.onclick = function (e) {
return false;
};
that = {
method: function () {
return this.datum;
},
datum: 0
};
應該儘量減少全局函數的使用,當一個函數要被立即調用時,整個調用表達式應該被包裝在括號中,這樣就可以清楚地看到產生的值是函數的結果,而不是函數本身。
var collection = (function () {
var keys = [];
var values = [];
return {
get: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
return values[at];
}
},
set: function (key, value) {
var at = keys.indexOf(key);
if (at < 0) {
at = keys.length;
}
keys[at] = key;
values[at] = value;
},
remove: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
keys.splice(at, 1);
values.splice(at, 1);
}
}
};
}());
Names
名字應該只由26個大寫或者小寫字母(A .. Z, a .. z),十個數字(0 .. 9)、以及下劃線組成。儘量避免使用兩個國家以上的字符,那樣可能造成閱讀和理解上的麻煩。在名字中不應該使用反斜槓和美元符號。在名字中,不要使用下劃線作爲第一個字符或者最後一個字符,下劃線作爲第一個和最後一個字符常用來表示私有的,但是在程序語言中並沒有實際的語義。如果私有性是很重要的,應該儘量使用關閉,而不是使用缺少約束力的約定。大多數屬性和函數值應該使用小寫字母開始。必須和new一起使用的構造函數名字應該以大寫字母開始。Javascript的new省略並不會在編譯時和運行時產生警告和錯誤。但是會產生不好的事情,所以我們唯一能做的是用大寫的形式約定。瀏覽器中的所有全局變量應該被大寫。
語句
簡單語句
每行最多包含一條語句,並以分號結束,函數或者對象字面量賦值語句也必須以分號結束。
JavaScript允許任何表達式成爲語句。這很容易造成誤解,特別是存在分號作爲嵌入成分時。任何表達式應該被用作語句,例如賦值,調用,delete.
複合語句
1)混合語句是指被包含在花括號中的語句。嵌套的語句應該縮進更多的單位
2)左花括號應在複合語句開始行的末尾
3)右花括號應該重新開始一行,並與含有相對應的左花括號的行的開始對齊
4)在控制語句中,大括號應該用於所有語句,甚至是單個語句,這樣可以很方便的增加新的語句,且不易引入錯誤。
標籤
除了while、do、for、switch,其它語句是不允許被標記的。
返回
返回值必須和return關鍵字必須在同一行。
If語句
if語句應該是如下格式
if (condition) {
statements
}
if (condition) {
statements
} else {
statements
}
if (condition) {
statements
} else if (condition) {
statements
} else {
statements
}
For語句
for語句存在如下格式:
for (initialization; condition; update) {
statements
}
While語句
while (condition) {
statements
}
Do語句
do {
statements
} while (condition);
Switch語句
switch (expression) {
case expression:
statements
default:
statements
}
Try語句
try {
statements
} catch (variable) {
statements
}
try {
statements
} catch (variable) {
statements
} finally {
statements
}
Continue語句
儘量避免使用continue語句,它會導致控制語句的結構混亂
With語句
with語句應該避免使用
{} 和 []
使用{}代替new Object(),[]代替new Array()
當成員名是連續的整數時,使用數組,當成員名是字符串或者其他類型時使用對象
逗號
反對使用逗號
賦值表達式
在if和while條件部分反對賦值表達式
if (a = b) {
同時也應該避免
if (a == b) {
=== and !== Operators
應該儘量使用=== 和 !==,避免使用==和!=
易混淆的加減號
不要在a+後面跟着+好,避免和++混淆,此處可以使用括號使表達式更清晰
total = subtotal + +myInput.value;可以更好的寫成
total = subtotal + (+myInput.value);
eval是邪惡的
Eval是javascript最被濫用的特性,避免使用它。
eval有別的名字。 不要使用Function構造函數。 不要將字符串傳遞給setTimeout或setInterval。