支持聯繫支持|系統狀態系統狀況
頁面內容

    概念:模塊設計模式

    在本主題中,您將學習如何使用JavaScript模塊設計模式來減少代碼與網頁上其他腳本衝突的機會。

    範圍衝突

    在JavaScript中,當您使用var元素,它在所定義的函數範圍內。如果不使用定義變量var,然後為其分配全局範圍。這意味著全局變量很容易與頁面上的其他腳本發生衝突。

    讓我們看一個代碼示例。在以下代碼中,函數和變量位於頁面範圍內。

    // script 1
    var incrementCount = function() {
        count++;
    }
    
    var myButton = document.getElementById('buttonId');
    var count = 0;
    
    myButton.onclick = incrementCount;

    現在,假設腳本之外有一個函數也可以修改全局變量count變量。腳本的這種衝突可能導致意外的結果。

    // script 2
    var countVideos = function(videoList) {
        count = videoList.length;
    }

    結果:

    1. 用戶選擇myButton按鈕兩次,增加count可變的script 1
      • count = 2
    2. countvideos調用存在於其中的函數Script 2,也可以在您的網頁上。假設videoList包含10個項目。現在count全局變量的值為10
      • count = 10
    3. 下次用戶選擇myButton按鈕,count變量將返回意外結果。
      • 預期:count = 3
      • 實際:count = 11

    您可以嘗試避免腳本中的衝突,但是不能保證頁面中包含的第三方腳本不會使用相似的函數和變量名。

    匿名功能

    一種解決方案是將代碼包裝在匿名函數(也稱為閉包)中,該函數立即執行。其他腳本無法訪問閉包中的代碼。因此,這為您提供了創建私有函數和變量的方法。

    這是匿名函數的語法:

    • 第3行:包含了另一組括號,該括號告訴JavaScript在解析函數後立即執行該函數,而不是等待其他代碼來調用該函數。
    (function () {
        // your code
    }());

    封閉功能強大,因為它們在應用程序的整個生命週期內都提供隱私和狀態。對於閉包內部的代碼,所有變量和函數僅在閉包範圍內。但是,閉包內部的代碼仍然可以訪問任何全局變量或函數。

    全球

    儘管JavaScript具有稱為隱含全局變量的功能,但由於難以確定哪些變量是全局變量,因此可能使您的代碼難以管理。為了確定變量是否為全局變量,解釋器必須向後瀏覽範圍鏈以尋找var名稱匹配的語句。如果未找到,則假定該變量為全局變量。

    通過全球

    使用匿名函數,您可以顯式傳遞全局參數。這稱為將參數導入代碼中。

    這是一個例子:

    • 第1行:定義傳遞給函數的參數的名稱。請注意,它們不必與第3行中的名稱匹配。在這裡window對像被傳遞到名為window1
    • 第3行:通過window對象進入功能。
    (function( window1, undefined ) {
        ...
    })(window);

    由於僅傳遞了1個對象,但是有兩個參數,即undefined將是不確定的。

    typeof undefined == "undefined"

    如果您想要一種簡單的方法來檢查是否定義了其他變量,這可能會很方便。

    if(variable1 === undefined)

    出口全球

    您可能還想在匿名函數之外傳遞變量和函數。您可以使用return值。

    這是一個例子:

    • 第1行:將我們的匿名函數分配給BCLS。該值可以是您選擇的任何值。在此示例中,我們使用BCLS(Brightcove學習服務)。
    var BCLS = (function( window1, undefined ) {
        var object1 = {};
        object1.count = 1;
        object1.method = function () {
            ...
        }
        return object1;
    })(window);

    object1對象現在在全局上具有兩個公共屬性,即一個名為count和一個名為method。可以在我們的匿名功能之外通過以下方式訪問它們:

    • BCLS.object1.count
    • BCLS.object1.method

    完整的例子

    這是JavaScript模塊設計模式的一些完整示例。

    範例 1

    本示例說明如何使用模塊模式創建私有和公共變量和函數。

    • 私有變量:myvarmyvar2
    • 私人職能:fnamefname2
    • 公共變量:myvar3
    • 公共職能:fname3
    var BCLS = ( function() {
       var myvar = value,
           myvar2 = value;
    
       fname = function() {
            ...
       };
       fname2 = function() {
            ...
       };
    
       return {
            fname3 : function() {
                 ...
            },
            myvar3 = value;
       };
    }());

    範例 2

    本示例傳入全局對象,並公開一個公共函數。

    var BCLS = (function( window, document, videojs ) {
        var myvar = value;
    
        // use a global object passed into the anonymous function
        videojs.registerPlugin('overlay');
    
        fname = function() {
            ...
        }
        return {
          fname2 : function() {
                ...
            }
        }
    })(window, document, videojs);
    
    // call the public function fname2
    var newvar = BCLS.fname2();

    程式碼範例

    我們的一些代碼示例使用JavaScript模塊設計模式,您可以查看它們以獲取有關如何實現此模式的想法。