[JS進階] 編寫可維護性代碼

1 可維護性代碼的特色

  1. 可理解性:其餘人能夠接手代碼並理解它的意圖,無需原開發人員花太多時間解釋!
  2. 直觀性:代碼中的東西一看就能明白,儘管其操做過程複雜。
  3. 可適應性:代碼以一種數據上的變化不要求徹底重寫方法。
  4. 可擴展性:在代碼架構上可對核心功能的擴展。
  5. 可調式性:出錯時,代碼能夠給你足夠的信息來直接肯定問題所在。

2 代碼約定

因爲javascript語言的特色,咱們可編寫各類編程風格的代碼,從傳統的面向對象式到聲明式到函數式。造成一套良好的javascript代碼書寫約定可大大提升可維護性,這點對初學者來講絕對是沒有很注重的地方。 javascript

2.1 可讀性

  1. 縮進:在項目中統一代碼縮進,更易於閱讀,一種不錯也很常見的縮進大小爲四個空格,固然能夠是其餘數量。
  2. 註釋:其實咱們在編寫一些後臺代碼會常常把一個功能,一個業務邏輯,一個函數的代碼註釋起來,但咱們卻在編寫javascript卻常常忽略這些習慣。通常而言,在js中有如下這些地方須要註釋:
  • 函數和方法 :描述其目的和參數表明,返回值等。
  • 大段的代碼 :大段代碼一般是一個任務的代碼,應註釋描述任務。
  • 複雜的算法 :不是全部人都會你的算法,你須要把你的算法思路簡單描述下。
  • Hack :因各瀏覽器的差別,javascript的hack用於解決什麼問題應該描述清楚。

2.2 變量和函數的命名

  1. 變量名應該名詞:如car,person
  2. 函數名應以動詞開始:如getName(),返回布爾類型值的函數通常以is開頭,如:isEnable();
  3. 只要合乎邏輯,不用擔憂變量或者函數名的長度,長度問題能夠經過在你發佈代碼壓縮的時候得以解決。

2.3 變量類型透明

var car,person; //聲明兩個變量

如上代碼,因爲javascript中變量是鬆散類型的,咱們並不知道其中的car和person是什麼類型的數據,不夠透明,咱們能夠經過一下兩種方式緩解這種問題: php

  1. 初始化變量:經過初始化指定變量類型,但經過這種方式命名的對象沒法用於函數聲明中的參數。 css

    var car = null; //car是對象 var person = ''; //person是字符串 var count = -1; //count是整數 var found = false; //found是布爾型
  2. 匈牙利標記法:在變量名以前加上一個或多個字符表示數據類型。o - 對象,s - 字符串,i - 整數,f - 浮點數,b - 布爾型 html

    var oCar; //car是對象 var sPerson; //person是字符串 var iCount; //count是整數 var bFound; //found是布爾型

3 鬆散耦合

記得之前剛入門C#的時候,師兄常常跟我說‘高內聚低耦合’這詞,我也就含糊地點點頭,不少人可能也像我以前同樣,這詞耳熟能詳,但未真正實踐。 java

只要應用的某個部分過度依賴另外一部分,代碼就是耦合過緊,難於維護! 典型的問題:對象直接應用另外一個對象,而且修改其中一個的同時須要修改另外一個。 在咱們web應用中,咱們能夠經過一下方式解耦咱們的代碼: web

3.1 解耦HTML/JavaScript

在web應用中,咱們但願html專一於展現數據,css專一於樣式,javascript專一於行爲交互。可是有一些代碼會將html、javascript過於緊密地耦合在一塊兒。 算法

  1. 直接寫在HTML中javascript,使用包含內聯代碼的<script>元素或者是使用HTML屬性來分配事件處理程序。 編程

    <!--使用<script>標籤的緊密耦合 --> <script type="text/javascript"> document.write('hello,javascript'); </script> <!--使用時間處理程序屬性值的緊密耦合 --> <input type="button" value="click me" onclick="doSomething()"/>

    雖然這樣寫徹底正確,但出現javascript錯誤是,咱們須要判斷錯誤出如今HTML仍是在Javascript中,而且這還存在一個時間差問題,當我按下上面代碼的按鈕時,若此時javascript代碼並未加載完,此時變回引起錯誤。在實踐中,理想的情況應該是HTML和Javascript應徹底分離,使用引入外部文件來加載javascript。 數組

  2. 相反地,在javascript中也不能包含過多的HTMl 瀏覽器

    function insertMsg(msg){ var container = document.getElementById('container');
        container.innerHtml = '<div lcass=\"msg\"><p class=\"post\">' + msg + '</p></div>' }

當你在寫這樣的代碼的時候,我想你應該去找個js模板引擎來了。

對動態生成的HTML,對書寫CSS佈局,定位錯誤都比較難把控。

3.2 解耦CSS/Javascript

上面說了,CSS和JS都應該各司其職,不能有太大的親密動做,秀恩愛,死得快 囧~~~。
這個問題並不能說徹底解耦css和js,由於在現代web應用中經常須要javascript來更改樣式,可是咱們仍是儘可能使他們分離。

// CSS對JS的緊密耦合 element.style.color = 'red';
element.style.backgroundColor= 'blue';

這樣的代碼在之後修改樣式的時候須要同時修改CSS和JS,可麻煩了。

//這樣就ok了 element.className = 'color'; //color是樣式類

還有一個就是不能在CSS中寫CSS表達式,這應該是都知道的了。

3.3 解耦應用邏輯和事件處理程序

每一個web應用程序都有至關多的事件處理程序,監聽着大量不一樣的事件,然而,不多能有仔細將應用邏輯從事件處理程序中分離的,以下:

function checkValue(e){
   e = e || window.event; var target = e.target || e.srcElement; if(target.value.length < 5){ //省略一堆邏輯處理代碼... }
}

將上面的代碼重寫爲:

function checkValue(value){ if(value.length < 5){ //省略一堆邏輯處理代碼... }
   } function handleBlur(e){
       e = e || window.event; var target = e.target || e.srcElement;
       checkValue(target.value); //調用應用邏輯處理函數 }

這樣寫有什麼好處呢?

  1. 當有不一樣的方式觸發相同的相同過程事件的時候,這時只需調用應用邏輯處理函數便可。
  2. 應用邏輯處理函數能夠在不添加到事件的狀況下單獨測試。

4 編程實踐

在企業環境中建立的web應用每每同時由大量人員一同創做。在這種狀況下的目標是確保每一個人所使用的瀏覽器環境都有一致和不變的規則,所以,咱們須要堅持一下的一些編程實踐:

4.1 避免全局變量

在一個js文件中,最多容許有一個全局變量,讓其餘對象和函數包含在其中,由於過多的全局變量會消耗大量內存。

//兩個全局變量 var name = 'jozo'; function sayName(){
  alert('jozo');
}

上面的代碼有兩個全局變量,變量name和函數sayName(),其實能夠建立一個變量包含它們:

//一個全局變量 --推薦 var person = {
    name:'jozo',
    sayName : function(){
        alert(this.name);
    }
}

這樣一個全局變量延伸開來就是‘空間的概念’了,不會與其餘功能產生衝突,有助於消除功能做用域之間的混淆。

4.2 避免與null進行比較

function sortArray(values){ if(values != null){
        values.sort(比較函數);
    }
}

上面代碼中的if語句應該檢測values是不是數組,但若是與null做比較的話,字符串,數字等都會經過,致使函數拋出錯誤。這裏是數組,那麼咱們就應該檢測其是否爲數組:

function sortArray(values){ if(values instanceof Array){
        values.sort(比較函數);
    }
}

所於當咱們遇到與null做比較的代碼的時候,咱們應該用下面的技術替換:

  1. 若是值爲引用類型,則用instanceof 操做符檢查其構造函數。
  2. 若是值是基本類型,則用typeof操做符檢查其類型。

4.3 使用常量

function validate(value){ if(!value){
        alert('不存在');
        location.href = '/errors/invalid.php';
    }
}

如今,我想把‘不存在’改成‘該數據不存在!’,把跳轉路徑也改了,我得回到函數中找到對應的代碼去修改,而每次修改邏輯代碼,都有可能引入錯誤的風險。因此咱們能夠把數據單獨定義爲常量,與應用邏輯分離:

var Constans = {
    ERRORMSG: '不存在',
    ERRORPAGE:'/errors/invalid.php' }; function validate(value){ if(!value){
        alert(Constans.ERRORMSG );
        location.href = Constans.ERRORPAGE ;
    }
}

這樣咱們修改靜態文本內容的時候就無需去動邏輯函數了,甚至能夠把Constans單獨一個文件。那麼什麼樣的數據須要抽出來作常量呢?

  1. 重複值:任何在多處用到的值。
  2. 用戶界面字符串:任何用於顯示給用戶提示信息的字符串。
  3. URLs:在WEB項目中,資源路徑可能常常變動。在一個公共的地方存起來,修改起來更容易!
  4. 任何可能在之後會改變的值。

5 總結

全部編程語言都須要可維護性良好的代碼,這個很重要,由於大部分開發人員都花費大量時間維護他人的代碼。爲了減輕相互的負擔,從今天起我要作個好人,寫好代碼! o(╯□╰)o

相關文章
相關標籤/搜索