概念:模塊設計模式

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

使用 JavaScript 變量

在 ES2015(ES6)發布之前,JavaScript 變量用來聲明使用var關鍵字。但是,隨著 ES6 的引入,letconst被添加為一種新的方式來聲明變量。這經常引發關於應該使用哪個關鍵字以及何時使用的問題。

以下是在 JavaScript 中聲明變量的不同方式的簡短說明。

使用變量

使用var是變量聲明的最古老的方法。在函數中定義時,any var僅限於該函數,但在函數外部定義時,a var是全局的。

// Global Declaration
var variable = value;

const varExampleFunction = () => {
    // Local Declaration
    var variable = value;
}

使用讓

let聲明是用 ES6 引入的,這種類型的聲明是塊範圍的,這意味著聲明的變量只let能在定義它的塊或函數中訪問。

const letExampleFunction = () => {
    let variable = value;
}

使用常量

因為let,也const被引入了 ES6。這就是為什麼這兩個聲明非常相似。主要區別在於指const向內存中保存常量值的數據,並且const引用變量不能重新分配給內存中的不同對象。

 const constExampleFunction = () => {
    const variable = value;
}

範圍衝突

在 JavaScript 中,當您使用varletconst元素定義變數時,它會在其定義的函數範圍內。全局變量容易與頁面上的其他腳本發生衝突。

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

// script 1
const incrementCount = () => {
    count++;
}

const myButton = document.getElementById('buttonId');
let count = 0;

myButton.onclick = incrementCount;

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

// script 2
const countVideos = 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在解析函數後立即執行該函數,而不是等待其他代碼來調用該函數。
( () => {
    // your code
}());

另一個語法示例:

var res = function( [arguments] ) { ... }

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

全球

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

通過全球

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

這是一個例子:

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

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

typeof undefined == "undefined"

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

if(variable1 === undefined)

出口全球

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

這是一個例子:

  • 第1行:將我們的匿名函數分配給BCLS。該值可以是您選擇的任何值。在此示例中,我們使用BCLS(Brightcove學習服務)。
const BCLS = ( ( 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
const BCLS = ( () => {
   var myvar = value,
       myvar2 = value;

   fname = () =>  {
        ...
   };
   fname2 = () =>  {
        ...
   };

   return {
        fname3 : () =>  {
             ...
        },
        myvar3 = value;
   };
}());

範例 2

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

const BCLS = ( ( window, document, videojs ) => {
  var myvar = value;

  // use a global object passed into the anonymous function
  videojs.registerPlugin('overlay');

  fname = () => {
      ...
  }
  return {
    fname2 : () => {
          ...
      }
  }
})(window, document, videojs);

// call the public function fname2
var newvar = BCLS.fname2();

代碼樣本

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