寫JS程式碼差不多也有兩年了吧,從剛開始的“初生牛犢不怕虎”亂寫一通到後來也慢慢知道去規範一下自己寫的程式碼。這種感覺就像是程式碼是你的作品,你希望它保持一份不僅乾淨而且也優雅的姿勢。所以後來慢慢規範了自己寫的程式碼,再後來覺得僅僅規範自己的程式碼還不行,這個團隊其他人的也需要保持一致,再再後來就開始嘗試寫了一份程式碼規範,用於規範團隊的程式碼質量。網上有不少講程式碼規範的書,我也就不再獻醜了,大家可以去看看阿里\百度\騰訊他們的程式碼規範,寫的非常不錯。我就僅僅把自己遇到的嘗試做一下總結,這些可能別人也總結過無數次了,歡迎吐槽交流,也希望對你有點兒幫助。
1、減少全域性汙染
我們都知道javascript使用function來管理自己的作用域,一個定義在函式內的變數對外是不可見的,這有點類似於其它語言裡的私有變數。對於javascript的執行環境來說一般都有一個全域性變數,在所有的函式外可以用this來指引,例如在瀏覽器端是window。但是當過多的在全域性執行環境下定義變數會造成各種苦逼的事情,比方說你定義的變數被其他人定義的同名變數覆蓋掉,或者你未來定義的變數把你過去定義的同名變數也覆蓋掉,而且過多的全域性變數放在執行對戰裡還會造成記憶體的浪費等等不優化的情況發生。我就不再具體講沒個苦逼的事情是如何苦逼了,僅僅講講可能會導致這種情況發生的不好的示例吧。
①宣告變數忘記使用“var”的情況。
1 2 3 4 5 6 7 |
var sample = function () { var a1 = "hello"; a2 = "world"; }; sample(); alert(a1);//undefined alert(a2);//world |
如你所見,a2因為忘記使用var導致了它成為了全域性的變數,這樣就有可能造成其它地方的修改覆蓋它或者將其它地方的變數覆蓋等(忘記var也會使得該變數可以delete)。正確的做法是,所有的變數都使用“var”,並且儘量都生命在函式體的頭部,這樣一目瞭然。如下:
1 2 3 4 5 6 |
var sample = function () { var a1 = true,//標識位1 a2 = true, //標識位2 a3 = false;//標識位3 //do some logic }; |
(注:用“,”號隔開變數可以避免過多使用”var”。)
②變數名提升。
javascript中函式內所有使用var宣告的變數都會提升到函式體頭部,這也是很多人容易犯錯的一點。具體來講就是:
1 2 3 4 5 6 7 |
myname = "global"; function sample() { alert(myname); // "undefined" var myname = "local"; alert(myname); // "local" } sample(); |
如你所見,第一個alert出來的並非global。原因在於,函式sample內部宣告的myname會提升到函式體頂部,而原語句的地方才是正在賦值的地方。在宣告和賦值直接引用的話肯定是undefined了。其執行效果如下:
1 2 3 4 5 6 7 8 |
myname = "global"; function sample() { var myname;//沒有賦值 alert(myname); // "undefined" myname = "local";//此處賦值 alert(myname); // "local" } sample(); |
所以一個重要的經驗就是,在函式體講所有的var宣告的東西都拿到函式體頂部,以免造成不必要的錯誤。
2、for迴圈。
我們習慣將for迴圈寫成如下形式:
1 2 3 |
for (var i = 0; i < myarray.length; i++) { //logic } |
看似沒有問題,但是如果myarray是讀取的DOM的節點,那麼每一次迴圈都要去DOM裡選取節點再做判斷,非常影響效能。可能數量不大感覺不錯來,多了就非常嚴重了。所以,for迴圈判斷條件裡儘量不要使用涉及到DOM操作的動作。優化如下:
1 2 3 |
for (var i = 0, max = myarray.length; i < max; i++) { // logic } |
另外一個就是使用for-in迴圈物件的話會讀取物件從原型鏈裡的屬性,如果這不是希望的,那麼可以用一個判斷hasOwnProperty(i)去掉它。
3、用“===”取代“==”
前者是嚴格判斷,後者會提前進行隱式的型別轉換。
4、不使用eval()
5、統一縮排大小(無論用tab或者2個或者4個空格,團隊統一即可),任何用花括號括起來並換行的都進行縮排。
6、花括號{}
for迴圈或者if判斷等,即使只有一行,也要換行並用{}括起來。
7、空格
任何“;”後空一格、for迴圈中初始化“,”後空一格、陣列中”,”後空一格、物件中“:”後空一格、如:
1 2 3 4 |
for (var i = 0, j = 1; i < 10; i += 1){ var some = [1, 2, 3]; var obj = {aa: 1, bb: 2} } |
函式引數裡“,”後空一格、函式宣告中花括號前空一格、函式表示式中括號前後各空一格,如:
1 2 3 |
func(a, b, c){}; function func() {}; var func = function () {}; |
所有的操作符前後都跟一個空格,如:
1 2 3 4 5 6 |
var d = 0, a = b + 1; if (a && b && c) { d = a % c; a += d; } |
8、命名規則
構造器函式首字母大寫,如:
1 |
function Person() {...} |
變數用駝峰式,如:
1 |
getFirstName() |
常量全用大寫字母,如:
1 |
var PI = 3.1415926; |
私有函式用下劃線開頭,如:
1 2 3 4 5 6 7 8 |
var person = { _setSext: function () { // ... }, _setName: function () { // ... } }; |
9、寫註釋
這一步非常關鍵,因為你寫的程式碼別人不一定看得懂,你寫的將來你也不一定輕易能看懂。所以良好的註釋習慣可以事半功倍。
感謝你這麼大的耐性,天馬行空的對著自己寫的程式碼總結了一點兒,希望多少對你有點啟發。