JS 101 - Module Pattern

前面介紹過JS中的namespace, 看起來好像我們已經(jīng)成功解決了全局空間沖突的問題了。 但前面提到的方法有一個缺點——我們無法限制對方法和變量的訪問,他們都是公開的。另一個不夠優(yōu)雅的地方就是引入了大量的this和prototype聲明,略顯繁瑣。今天要講的這個設計模式提供了一種易讀的方法解決了以上問題,也是JS中最常用的設計模式之一。

讓我們先來看一個看起來很奇怪的函數(shù):

(function() {
// some code
})();

這個有許多括號的函數(shù)叫做立即調(diào)用函數(shù)表達式IIFE,其含義就是聲明一個函數(shù)并立即執(zhí)行該函數(shù)。為什么我們要如此大費周章的弄一個立刻執(zhí)行的函數(shù)呢?回顧一下JS的基礎知識,我們知道JS中并沒有block scope這個概念,只有function才擁有自己的 scope。因此IIFE實際上創(chuàng)建了一個封閉的scope,用來模擬private scope。

對前面提到的namespace稍作修改:

var MODULE = (function() {
// some code
})();

可得到一個名為MODULE的私密封裝空間, 外界無法訪問該空間內(nèi)部。 這里為了提高可讀性,用大寫聲明模塊。

如果我們在MODULE內(nèi)部有一個叫做privateMethod的函數(shù):

var MODULE = (function() {

  var privateMethod = function() {
  };

})();

外界無法用類似MODULE.privateMethod()這樣的手段訪問該函數(shù), 我們成功創(chuàng)建了一個private method!同理,我們也可以創(chuàng)建private variable。

當我們創(chuàng)建了封閉的私密空間后,該空間對外界而言就是一個看不見內(nèi)部構(gòu)造的黑盒。但如果這個黑盒不能給我們提供服務,他就失去了存在的意義。為了給外界提供服務,我們還需要給這個黑盒子設置一組借口。就好比插座, 我們雖然看不到埋在墻里的部分是什么,但我們知道只要用適配的插頭接入插座, 就可以得到一定標準的電流來驅(qū)動電器。

Module Pattern中的接口由return實現(xiàn):

var MODULE = (function() {

  return {
    publicMethod: function() {
    }
  };

})();

return返回一個對象字面量,這個對象字面量就是外界可訪問的接口 : MODULE.publicMethod();

該接口可包含多個方法,這些方法可以訪問private variable和private function:

var MODULE = (function() {

  var _privateName = '';
  var privateMethod = function() {
  };

  return {
    publicGetName: function() {
      return _privateName;
    },
    publicOne: function() {
    },
    publicTwo: function() {
    }
  };
})();

于是一個幾乎完整的private scope就誕生了。在這里不得不佩服JS的前輩們,能在這么贏弱的語法上硬是搭建出了相對完善的語言結(jié)構(gòu)。

上面這個模式已近完整,可應對絕大部分情況了。但我們還可以跟前面講過的namespace結(jié)合起來,讓return部分更清晰明了:

var MODULE = (function() {

  var publicObject = {};

  var privateMethod = function() {};  

  publicObject.methodOne = function() {};

  publicObject.methodTwo = function() {};

  return publicObject;
})();

通過將借口的方法整合進返回對象中,return語句現(xiàn)在簡潔了許多。另外也可以不返回對象,而是先聲明方法,然后返回公共方法的引用:

var MODULE = (function() {

  var privateMethod = function() {};  

  var methodOne = function() {};

  var methodTwo = function() {};

  return {
    methodOne: methodOne,
    methodTwo: methodTwo
  };
})();

就我個人而言,我一般采用后兩種方法。若接口中方法較少教簡單,也可以采用第一種方法。

此外,module 也可以接收參數(shù):

var MODULE = (function (param) {
  // some code
})(param);

甚至接收另一個module作為參數(shù):

var ModuleTwo = (function (Module) {
    // access to `Module`
})(Module);

于是你會看到許多看起來不可思議又精妙絕倫的module pattern代碼,就留給各位自己去探索吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,665評論 19 139
  • { "Unterminated string literal.": "未終止的字符串文本。", "Identifi...
    栗子雨閱讀 8,078評論 0 3
  • { "Unterminated string literal.": "未終止的字符串文本。", "Identifi...
    一粒沙隨風飄搖閱讀 11,349評論 0 3
  • "Unterminated string literal.": "未終止的字符串文本。", "Identifier...
    兩個心閱讀 8,560評論 0 4
  • 我基本從來不寫工作的事兒。 因為工作實在沒啥好寫的,不就是工作唄。 然後今天打算稍微寫一點,就寫JS吧。 我一直相...
    LostAbaddon閱讀 1,558評論 22 21

友情鏈接更多精彩內(nèi)容