軟件bug的修復是昂貴的,而且隨着時間的推移,這些bug的成本也會增長,尤爲當這些bug潛伏並慢慢出如今已經發布的軟件中時。當你發現bug 的時候就當即修復它是最好的,此時你代碼要解決的問題在你腦中仍是很清晰的。不然,你轉移到其餘任務,忘了那個特定的代碼,一段時間後再去查看這些代碼就 須要:javascript
另外一個相關軟件開發生命的事實是,讀代碼花費的時間要比寫來得多。有時候,當你專一併深刻思考某個問題的時候,你能夠坐下來,一個下午寫大量的代碼。css
你的代碼很能很快就工做了,可是,隨着應用的成熟,還會有不少其餘的事情發生,這就要求你的進行進行審查,修改,和調整。例如:html
因爲這些變化,不多人力數小時寫的代碼最終演變成花數週來閱讀這些代碼。這就是爲何建立可維護的代碼對應用程序的成功相當重要。java
可維護的代碼意味着:
提示: 不遵照這些原則代碼也能運行起來。只是可能出現難以維護的現象。規範就像一種模式,你們按照一種模式來,那麼閱讀其餘人的代碼,成本就下降了。git
function func() { var a = 1, b = 2, sum = a + b, myobject = {}, i, j; // function body... }
注意:在es6中,使用let 定義,可能出現'暫時性死區', 具體想知道什麼叫作'暫時性死區' , 請查看阮一峯 ECMAScript 6 入門es6
// 次佳的循環 for (var i = 0; i < myarray.length; i++) { // 使用myarray[i]作點什麼 } //更好的方式 for (var i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]作點什麼 }
**JSLint提示您這樣作,緣由是++和–-促進了「過度棘手(excessive trickiness)」。//zxx:這裏比較難翻譯,我想本意應該是讓代碼變得更加的棘手
若是你直接無視它,JSLint的plusplus選項會是false(默認是default)。**github
還有兩種變化的形式,其又有了些微改進,由於:正則表達式
//第一種變化的形式:
var i, myarray = [];
for (i = myarray.length; i–-;) {
// 使用myarray[i]作點什麼
}api
//第二種使用while循環:數組
var myarray = [],
i = myarray.length;
while (i–-) {
// 使用myarray[i]作點什麼
}
面兩種狀況優於前面兩種狀況。
for-in循環應該用在非數組對象的遍歷上,使用for-in進行循環也被稱爲「枚舉」。
從技術上將,你可使用for-in循環數組(由於JavaScript中數組也是對象),但這是不推薦的。由於若是數組對象已被自定義的功能加強,就可能發生邏輯錯誤。另外,在for-in中,屬性列表的順序(序列)是不能保證的。因此最好數組使用正常的for循環,對象使用for-in循環。
有個很重要的hasOwnProperty()方法,當遍歷對象屬性的時候能夠過濾掉從原型鏈上下來的屬性
// 對象 var man = { hands: 2, legs: 2, heads: 1 }; // 在代碼的某個地方 // 一個方法添加給了全部對象 if (typeof Object.prototype.clone === "undefined") { Object.prototype.clone = function () {}; } ==================================================================== // for-in 循環 for (var i in man) { if (man.hasOwnProperty(i)) { // 過濾 console.log(i, ":", man[i]); } } /* 控制檯顯示結果 hands : 2 legs : 2 heads : 1 */ ========================================================================== // 反面例子: // for-in loop without checking hasOwnProperty() for (var i in man) { console.log(i, ":", man[i]); } /* 控制檯顯示結果 hands : 2 legs : 2 heads : 1 clone: function() */
增長內置的構造函數原型(如Object(), Array(), 或Function())挺誘人的,可是這嚴重下降了可維護性,由於它讓你的代碼變得難以預測。使用你代碼的其餘開發人員極可能更指望使用內置的 JavaScript方法來持續不斷地工做,而不是你另加的方法。
所以,不增長內置原型是最好的。你能夠指定一個規則,僅當下面的條件均知足時例外:
你清楚地文檔記錄並和團隊交流了變化。
if (typeof Object.protoype.myMethod !== "function") { Object.protoype.myMethod = function () { // 實現... }; }
通常狀況下,強烈不建議使用
JavaScript的變量在比較的時候會隱式類型轉換。這就是爲何一些諸如:false == 0 或 「」 == 0 返回的結果是true。爲避免引發混亂的隱含類型轉換,在你比較值和表達式類型的時候始終使用===和!==操做符。
var zero = 0; if (zero === false) { // 不執行,由於zero爲0, 而不是false } // 反面示例 if (zero == false) { // 執行了... }
若是你如今的代碼中使用了eval(),記住該咒語「eval()是魔鬼」。此方法接受任意的字符串,並看成JavaScript代碼來處理。當有 問題的代碼是事先知道的(不是運行時肯定的),沒有理由使用eval()。若是代碼是在運行時動態生成,有一個更好的方式不使用eval而達到一樣的目 標。例如,用方括號表示法來訪問動態屬性會更好更簡單:
// 反面示例 var property = "name"; alert(eval("obj." + property)); // 更好的 var property = "name"; alert(obj[property]);
代碼沒有縮進基本上就不能讀了。惟一糟糕的事情就是不一致的縮進,由於它看上去像是遵循了規範,可是可能一路上伴隨着混亂和驚奇。重要的是規範地使用縮進。
一些開發人員更喜歡用tab製表符縮進,由於任何人均可以調整他們的編輯器以本身喜歡的空格數來顯示Tab。有些人喜歡空格——一般四個,這都無所謂,只要團隊每一個人都遵循同一個規範就行了。這本書,例如,使用四個空格縮進,這也是JSLint中默認的縮進。
什麼應該縮進呢?規則很簡單——花括號裏面的東西。這就意味着函數體,循環 (do, while, for, for-in),if,switch,以及對象字面量中的對象屬性。下面的代碼就是使用縮進的示例:
function outer(a, b) { var c = 1, d = 2, inner; if (a > b) { inner = function () { return { r: c - d }; }; } else { inner = function () { return { r: c + d }; }; } return inner; }
// 糟糕的實例 for (var i = 0; i < 10; i += 1) alert(i); // 好的實例 for (var i = 0; i < 10; i += 1) { alert(i); }
這個實例中,仁者見仁智者見智,但也有個案,括號位置不一樣會有不一樣的行爲表現。這是由於分號插入機制(semicolon insertion mechanism)——JavaScript是不挑剔的,當你選擇不使用分號結束一行代碼時JavaScript會本身幫你補上。這種行爲可能會致使麻 煩,如當你返回對象字面量,而左括號卻在下一行的時候
// 警告: 意外的返回值 function func() { return // 下面代碼不執行 { name : "Batman" } } // 警告: 意外的返回值 function func() { return undefined; // 下面代碼不執行 { name : "Batman" } }
空格的使用一樣有助於改善代碼的可讀性和一致性。在寫英文句子的時候,在逗號和句號後面會使用間隔。在JavaScript中,你能夠按照一樣的邏輯在列表模樣表達式(至關於逗號)和結束語句(相對於完成了「想法」)後面添加間隔。
適合使用空格的地方包括:
使用空格分開全部的操做符和操做對象是另外一個不錯的使用,這意味着在+, -, *, =, <, >, <=, >=, ===, !==, &&, ||, +=等先後都須要空格。
// 寬鬆一致的間距 // 使代碼更易讀 // 使得更加「透氣」 var d = 0, a = b + 1; if (a && b && c) { d = a % c; a += d; } // 反面例子 // 缺失或間距不一 // 使代碼變得疑惑 var d = 0, a = b + 1; if (a&&b&&c) { d=a % c; a+= d; }
最後須要注意的一個空格——花括號間距。最好使用空格:
//{} 空格
if (4) {
console.log(1)
} else if (3) {
console.log(1)
}
var a = {}
JavaScript並無類,但有new調用的構造函數:
var adam = new Person();
由於構造函數仍僅僅是函數,僅看函數名就能夠幫助告訴你這應該是一個構造函數仍是一個正常的函數。
命名構造函數時首字母大寫具備暗示做用,使用小寫命名的函數和方法不該該使用new調用:
function MyConstructor() {...} function myFunction() {...}、
當你的變量或是函數名有多個單詞的時候,最好單詞的分離遵循統一的規範,有一個常見的作法被稱做「駝峯(Camel)命名法」,就是單詞小寫,每一個單詞的首字母大寫。
## 4.3 註釋(Writing Comments)
你必須註釋你的代碼,即便不會有其餘人向你同樣接觸它。一般,當你深刻研究一個問題,你會很清楚的知道這個代碼是幹嗎用的,可是,當你一週以後再回來看的時候,想必也要耗掉很多腦細胞去搞明白到底怎麼工做的。很顯然,註釋不能走極端:每一個單獨變量或是單獨一行。可是,你一般應該記錄全部的函數,它們的參數和返回值,或是任何不尋常的技術和方法。要想到注 釋能夠給你代碼將來的閱讀者以諸多提示;閱讀者須要的是(不要讀太多的東西)僅註釋和函數屬性名來理解你的代碼。例如,當你有五六行程序執行特定的任務, 若是你提供了一行代碼目的以及爲何在這裏的描述的話,閱讀者就能夠直接跳過這段細節。沒有硬性規定註釋代碼比,代碼的某些部分(如正則表達式)可能註釋 要比代碼多。
css規範咱們偉大的張旭鑫老師,講的很清楚。面向屬性的命名
這是比較好的命名規範。簡介來講,就是咱們先定義好一些經常使用基礎類樣式。組件則使用less,或者sass進行組裝,造成便可。