1. 程式人生 > 其它 >編寫可維護的JavaScript程式碼

編寫可維護的JavaScript程式碼

  • 什麼是可維護性?
  • JavaScript如何實現可維護性程式碼?

一、什麼是可維護性?

1.1什麼是可維護性?

修改bug和新增迭代功能一個專案不可避免的基本操作需求,程式碼良好的閱讀性、程式碼結構的一致性、預留未來迭代的空間、統一程式碼規範、充分必要的註釋文件是可維護性的程式碼必須具備的特徵。

為了保證實現的程式碼良好的可維護性,首先是規避語言本身容易引發bug的問題,保持良好的程式碼習慣,嚴格按照開發規範執行專案的開發。深入瞭解程式語言的語法、特性、底層實現邏輯,合理的使用語言的各種功能和API。

二、JavaScript如何實現可維護性程式碼?

要想實現良好的可維護性JavaScript專案,首先就需要了解JavaScript中容易引發bug的問題,正確的理解JavaScript語法與API。然後基於熟練的語言應用能力,制定合理的開發規範實現專案的開發。接下來列舉總結一些常見的JavaScript容易引發bug的語法等問題,並簡單說明和提供解決方案,具體相關詳細內容參考《JavaScript模式》。

2.1變數宣告可能引發的Bug:

  • 儘量不使用全域性變數,一是JS可以直接使用變數,甚至無需宣告;二是JS有暗示全域性變數的概念,即任何變數如果未經宣告使用,就會預設作用成全域性變數。
  • delete只能釋放物件的屬性,不能釋放變數;有時候也能刪除全域性變數是因為該全域性變數採用的反模式(即未使用var等宣告符)宣告的變數,本質上這類全域性變數被視作全域性物件window的屬性,而非全域性作用域上的變數。
  • 獲取可靠的全域性物件,可以通過非new執行函式內this獲取,因為js中非new執行函式其this預設指向全域性物件。當然可以使用ES5的嚴格模式,阻止window作為自定義變數。
var
global = (function(){ return this; }());
  • 使用單一var模式:即再函式頂部使用一個var,通過逗號間隔的方式將所有該作用的變數統一宣告;其一這有利於以後閱讀程式碼,其二函式本省執行時首相會將所有變數進行提升,詳細參考javasrcipt的作用域和閉包(二)續篇之:函式內部提升機制與Variable Object。ES6中新增了let,const新的變數宣告符但這依然不影響這一原則,依然建議將所有變數宣告寫函式的頂部。
  • 避免使用eval(),其一eval()會將一段字串作為JS程式碼編譯執行,這存在巨大的安全隱患,特別是可能用於解析執行從網路上獲取的JSON格式JS程式碼,非常容易被惡意程式碼入侵;其二eval()的執行會導致不可預測的暗示全域性變數,由此引發意想不到的BUG。如果不可避免的需要使用eval,可以使用一個立即執行函式將其包括,可以規避其汙染全域性變數的可能。
var jsStr = "var n = 3; console.log(n);";
(function(){
    eval(jsStr);    //3
}());
console.log(typeof n);    //undefined

2.2邏輯程式碼與迴圈結構如何寫出高效的程式碼?

  • 單變數模式:迴圈中用於作用迴圈邏輯的引數提取出來使用一個變數提取出來,避免每一次判斷都去列表中訪問對應屬性。在火狐3瀏覽器中使用單變數模式實現變數DOM列表可以提高3被速度,在IE7瀏覽器中可以提高170倍速度(這個測試資料是老版本瀏覽器)。這種模式除了執行速度的優化,還可以提高模板程式碼的複製,在同一中模式中的不同場景下,迴圈內部的操作不需要做任何修改,只需要將引數賦給對應的變數就可以實現設計模式的複用。
function fun(){
    var  i,  
          max,
          myArray = [];
          //...
    for(i = 0, max = myArray.length; i < max; i++){
        //...
    }
}
  • 使用for in和Object.prototype.hasOwnProperty規避物件中不允許列舉的屬性被迴圈操作,提高物件遍歷效率。
  • 使用switch替代多個if else結構,讓程式碼具備更好的可讀性和健壯性,儘量不要在switch中使用fall-throughs,也就是有意不適用break語句結束當前case,讓程式按順序一直往下執行。
  • 儘量使用絕對等於替代等於的邏輯判斷,提高程式碼的可讀性和健壯性。邏輯運算中的型別轉換可以參考這篇部落格:JS強制型別轉換之:比較運算到底發生了什麼?

2.3命名約定:

  • 建構函式首字母大寫(大駝峰)
  • 分隔單詞:小駝峰分隔法、下劃線分隔法兩種比較常見
  • 私有方法使用下劃線開頭,這一約定在ES6中可以使用ES6的私有方法語法實現

2.4其他實現可維護性JS程式碼的特性和編碼約定

  • 儘量不增加內建物件的原型屬性,隨意增加原型屬性會導致程式碼出現不可預測性的問題;但在某些情況下不得不在內建原型上新增屬性,比如為了向前相容、為了相容部分瀏覽器或裝置、為了統一團隊的其他成員的程式碼。
if(typeof Object.prototype.myMethod !== "function"){
    Object.prototype.myMethod = function(){ 
        //... 
    }
}
  • 使用parseInt()提取字串數值時注意開頭的字元若為0時,ES5之前該方法將以8進位制提取該數值,雖然在最新的瀏覽器中預設為10進位制,但是建議在使用parseInt轉換數值時在第二個引數上指定其轉換的計算進位制。
  • 保持良好的程式碼註釋和統一的風格,如果使用API文件工具提取註釋作為API文件使用,根據具體的工具實現。
  • 編碼:統一程式碼縮排的空格數;
    • if和for內部只有一條語句時,建議不省略大括號;
    • 大括號與所屬語句保持同一縱向位置對其。
    • 空格:for迴圈中各個部分分號之後建議使用空格分隔;
      • for迴圈中初始化多個變數逗號後建議使用空格分隔;
      • 陣列元素逗號後建議使用空格分隔;
      • 同一行的物件屬性建議逗號後使用空格分隔;
      • 函式中的引數逗號後建議使用空格分隔;
      • 函式宣告大括號之前建議使用空格分隔;
      • 在所有操作符的前後使用空格分隔,比如"=,+,-,>,||..."   
——生命自會找到蓬勃之路。