概念:模塊設計模式
範圍衝突
在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;
}
結果:
- 用戶選擇
myButton
按鈕兩次,增加count
可變的script 1
。count
= 2
- 的
countvideos
調用存在於其中的函數Script 2
,也可以在您的網頁上。假設videoList
包含10個項目。現在count
全局變量的值為10。count
= 10
- 下次用戶選擇
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
本示例說明如何使用模塊模式創建私有和公共變量和函數。
- 私有變量:
myvar
,myvar2
- 私人職能:
fname
,fname2
- 公共變量:
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模塊設計模式,您可以查看它們以獲取有關如何實現此模式的想法。