去年 11 月他有一個演講(Youtube),談到了好的 Javascript 編程風格是什麼。javascript
我很是推薦這個演講,它不只有助於學習 Javascript,並且能讓你心情舒暢,由於 Crockford 講得很幽默,時不時讓聽衆會心一笑。html
下面,我根據這個演講和 Crockford 編寫的代碼規範,總結一下"Javascript 編程風格"。java
所謂"編程風格"(programming style),指的是編寫代碼的樣式規則。不一樣的程序員,每每有不一樣的編程風格。程序員
有人說,編譯器的規範叫作"語法規則"(grammar),這是程序員必須遵照的;而編譯器忽略的部分,就叫"編程風格" (programming style),這是程序員能夠自由選擇的。這種說法不徹底正確,程序員當然能夠自由選擇編程風格,可是好的編程風格有助於寫出質量更高、錯誤更少、更易於 維護的程序。編程
因此,有一點應該明確,"編程風格"的選擇不該該基於我的愛好、熟悉程度、打字工做量等因素,而要考慮如何儘可能使代碼清晰易讀、減小出錯。你選 擇的,不是你喜歡的風格,而是一種可以清晰表達你的意圖的風格。這一點,對於 Javascript 這種語法自由度很高、設計不徹底成熟的語言尤爲重要。編程語言
1、大括號的位置模塊化
絕大多數的編程語言,都用大括號({})表示區塊(block)。起首的大括號的位置,有許多不一樣的寫法。函數
最流行的有兩種。一種是起首的大括號另起一行:學習
blockthis
{
...
}
另外一種是起首的大括號跟在關鍵字的後面:
block {
...
}
通常來講,這兩種寫法均可以接受。可是,Javascript 要使用後一種,由於 Javascript 會自動添加句末的分號,致使一些難以察覺的錯誤。
return
{
key:value;
};
上面的代碼的原意,是要返回一個對象,但實際上返回的是 undefined,由於 Javascript 自動在 return 語句後面添加了分號。爲了不這一類錯誤,須要寫成下面這樣:
return {
key : value;
};
所以,
規則1:表示區塊起首的大括號,不要另起一行。
2、 圓括號
圓括號(parentheses)在 Javascript 中有兩種做用,一種表示調用函數,另外一種表示不一樣的值的組合(grouping)。咱們能夠用空格,區分這兩種不一樣的括號。
規則2:調用函數的時候,函數名與左括號之間沒有空格。
規則3:函數名與參數序列之間,沒有空格。
規則4:全部其餘語法元素與左括號之間,都有一個空格。
按照上面的規則,下面的寫法都是不規範的:
foo (bar)
return (a+b);
if (a === 0) {...}
function foo (b) {...}
function (x) {...}
3、分號
分號表示語句的結束。大多數狀況下,若是你省略了句尾的分號,Javascript 會自動添加。
var a = 1
等同於
var a = 1;
所以,有人提倡省略句尾的分號。但麻煩的是,若是下一行的第一個字元(token)是下面這五個字符之一,Javascript 將不對上一行句尾添加分號:"("、"["、"/"、"+"和"-"。
x = y
(function (){
...
})();
上面的代碼等同於
x = y (function (){...})();
所以,
規則5:不要省略句末的分號。
4、with 語句
with 能夠減小代碼的書寫,可是會形成混淆。
with (o) {
foo = bar;
}
上面的代碼,能夠有四種運行結果:
o.foo = bar;
o.foo = o.bar;
foo = bar;
foo = o.bar;
這四種結果均可能發生,取決於不一樣的變量是否有定義。所以,
規則6:不要使用 with 語句。
5、相等和嚴格相等
Javascript 有兩個表示"相等"的運算符:"相等"(==)和"嚴格相等"(===)。
由於"相等"運算符會自動轉換變量類型,形成不少意想不到的狀況:
0 == ''// true
1 == true // true
2 == true // false
0 == '0' // true
false == 'false' // false
false == '0' // true
" \t\r\n " == 0 // true
所以,
規則7:不要使用"相等"(==)運算符,只使用"嚴格相等"(===)運算符。
6、語句的合併
有些程序員追求簡潔,喜歡合併不一樣目的的語句。好比,原來的語句是
a = b;
if (a) {...}
他喜歡寫成下面這樣:
if (a = b) {...}
雖然語句少了一行,可是可讀性大打折扣,並且會形成誤讀,讓別人誤覺得這行代碼的意思是:
if (a === b){...}
另一種狀況是,有些程序員喜歡在同一行中賦值多個變量:
var a = b = 0;
他覺得,這行代碼等同於
var a = 0, b = 0;
實際上不是,它的真正效果是下面這樣:
b = 0;
var a = b;
所以,
規則8:不要將不一樣目的的語句,合併成一行。
7、變量聲明
Javascript 會自動將變量聲明"提高"(hoist)到代碼塊(block)的頭部。
if (!o) {
var o = {};
}
等同於
var o;
if (!o) {
o = {};
}
爲了不可能出現的問題,不如把變量聲明都放在代碼塊的頭部。
for (var i ...) {...}
最好寫成:
var i;
for (i ...) {...,}
所以,
規則9:全部變量聲明都放在函數的頭部。
規則 10:全部函數都在使用以前定義。
8、全局變量
Javascript 最大的語法缺點,可能就是全局變量對於任何一個代碼塊,都是可讀可寫。這對代碼的模塊化和重複使用,很是不利。
規則 11:避免使用全局變量;若是不得不使用,用大寫字母表示變量名,好比 UPPER_CASE。
9、new 命令
Javascript 使用 new 命令,從建構函數生成一個新對象。
var o = new myObject ();
這種作法的問題是,一旦你忘了加上 new,myObject ()內部的 this 關鍵字就會指向全局對象,致使全部綁定在 this 上面的變量,都變成所有變量。
規則 12:不要使用 new 命令,改用 Object.create ()命令。
若是不得不使用 new,爲了防止出錯,最好在視覺上把建構函數與其餘函數區分開來。
規則 13:建構函數的函數名,採用首字母大寫(InitialCap);其餘函數名,一概首字母小寫。
10、自增和自減運算符
自增(++)和自減(--)運算符,放在變量的前面或後面,返回的值不同,很容易發生錯誤。
事實上,全部的++運算符均可以用"+= 1"代替。
++x
等同於
x += 1;
代碼變得更清晰了。有一個很好笑的例子,某個 Javascript 函數庫的源代碼中出現了下面的片斷:
++x;
++x;
這個程序員忘了,還有更簡單、更合理的寫法:
x += 2;
所以,
規則 14:不要使用自增(++)和自減(--)運算符,用+=和-=代替。
11、區塊
若是循環和判斷的代碼體只有一行,Javascript 容許該區塊(block)省略大括號。
下面的代碼
if (a) b (); c ();
原意多是
if (a) { b (); c ();}
可是,實際效果是
if (a) { b ();} c ();
所以,
規則 15:老是使用大括號表示區塊。