非侵入式JavaScript

非侵入式JavaScript[1]是一種將JavaScriptHTML結構抽離的設計概念,避免在HTML標籤中夾雜一堆onchange、onclick等屬性去掛載JavaScript事件,讓HTML與JavaScript分離,依模型-視圖-控制器的原則將功能權責清楚區分,使HTML也變得結構化容易閱讀。這個名稱並不是正式定義,它的基本原則包括:

新範式

行為與檔案標籤的分離

傳統上,JavaScript指令碼通常與HTML檔案的標籤放在一起。例如,以下是在HTML中註冊JavaScript事件處理程式的典型方法:

<input type="text" name="date" onchange="validateDate()"/>

HTML標籤的目的通常是描述檔案的排版結構,而不是網頁操作的程式行為。兩者的結合或許會對網站的可維護性產生負面影響,例如將呈現和內容相結合。在HTML中建立和參照的JavaScript指令碼行為,例如在單一元素上設置多個不同事件的處理程式,或在多個元素上設置相同的事件處理程式,或者在使用事件委派時,結果可能難以使用和維護。

非侵入式方案是以編程方式註冊需要的事件處理程式,而不是和網頁元素內嵌在一起。不同於前述那樣添加一個onchange屬性,相關的元素改用簡單的標識,例如以classid屬性和它們值當成指令碼參考的標識,或標記中一些其它的方式:

<input type="text" name="date" id="date"/>

當頁面首次載入到瀏覽器中時,執行的指令碼可以尋找每個相關元素,並相對應地進行設置:

window.addEventListener("DOMContentLoaded"function() {
    document.getElementById("date").addEventListener("change"function() {
        //code
    });
});

命名空間

非侵入式JavaScript應儘量減少將物件添加到運行環境,或全域的命名空間中。其它指令碼有可能覆蓋掉全域命名空間中,所建立的任何變數或函數;而這將導致發生不預期的結果時,卻難以除錯的困擾。JavaScript並沒有內建明確的命名空間機制,但利用語言設計很容易可產生需求的效果。Flanagan建議以Java編程的開發風格,將開發人員自己的域名反轉,作為全球獨一的名前空間發佈。

var org;
if (!org) {
    org = {};
} else if (typeof org != 'object') {
    throw new Error("org already exists and is not an object.");
}
if (!org.example) {
    org.example = {};
} else if (typeof org.example != 'object') {
    throw new Error("org.example already exists and is not an object.");
}

如在上面的org對象中,便可定義各種變數和函數。但還是建議在命名空間內,使用閉包進一步隔離,作為私有的變數和函數來使用,以共用介面回傳每個函數作用的結果。上列代碼可依照以下內容,改寫為非侵入式:

org.example.Highlight = function() {
    // Define private data and functions
    var highlightId = 'x';
    function setHighlight(color) {
        document.getElementById(highlightId).style.color = color;
    }

    // Return public pointers to functions or properties
    // that are to be public.
    return {
        goGreen: function() { setHighlight('green'); },
        goBlue:  function() { setHighlight('blue'); }
    }
}(); // End closure definition and invoke it.

從任何其它的模組,可以呼叫這些共用介面的方法,如下列:

org.example.Highlight.goBlue();

var h = org.example.Highlight;
h.goGreen();

以這種方式,每個模組-開發人員的代碼都包含在私有或唯一的命名空間中,並不會干擾或侵入任何其它代碼。

最佳實務

非侵入式Javascript的本質是增加了分離的行為層概念,而且這範式的提倡者認同一些相關的原則,如下列:

  • DOM指令碼,即遵循W3C DOM和事件模型,並避免使用某一瀏覽器特定的擴充功能。
  • 功能檢測,即在使用特定功能之前先檢查是否支援;對比相反於過去只檢測用戶端使用的瀏覽器(版本)。
  • 更一般來說,JavaScript最佳實務通常與其它程式語言(例如封裝抽象層,避免全域變數,有意義的命名法約定,使用適當的設計模式式和系統測試)平行。這些原則對大規模軟件工程開發非常重要,但過去的JavaScript設計過程中並不受重視。這些原則的採行,使JavaScript被認為是從「玩具」的手稿語言,轉變為正規編程發展工具的重要組成。

參考文獻

  1. ^ ASP.NET MVC 3高级编程. 清華大學出版社. 2012-06 [2016-06-30]. ISBN 978-7-302-28675-2. (原始內容存檔於2017-10-14). 
  2. ^ Keith, Jeremy. Behavioral Separation. 2006-06-20 [2016-09-13]. (原始內容存檔於2012-04-01). 
  3. ^ Olsson, Tommy. Graceful Degradation & Progressive Enhancement. 2007-02-06 [2016-09-13]. (原始內容存檔於2017-07-18). 

外部連結

參見