<dfn id="w48us"></dfn><ul id="w48us"></ul>
  • <ul id="w48us"></ul>
  • <del id="w48us"></del>
    <ul id="w48us"></ul>
  • javascript 單例模式詳解及簡單實(shí)例

    時間:2024-08-17 11:52:30 JavaScript 我要投稿
    • 相關(guān)推薦

    javascript 單例模式詳解及簡單實(shí)例

      在Javascript中,單例模式是一種最基本又經(jīng)常用到的設(shè)計(jì)模式,可能在不經(jīng)意間就用到了單例模式。

      本文將從最基礎(chǔ)的理論開始,講述單例模式的基本概念和實(shí)現(xiàn),最后用一個例子來講述單例模式的應(yīng)用。

      理論基礎(chǔ)

      概念

      單例模式,顧名思義就是只有一個實(shí)例存在。通過單例模式可以保證系統(tǒng)中一個類只有一個實(shí)例而且該實(shí)例易于外界訪問,從而方便對實(shí)例個數(shù)的控制并節(jié)約系統(tǒng)資源。如果希望在系統(tǒng)中某個類的對象只能存在一個,單例模式是最好的解決方案。

      基本結(jié)構(gòu)

      最簡單的單例模式起始就是一個對象字面量,它將有關(guān)聯(lián)的屬性和方法組織到一起。

      var singleton = { prop:"value", method:function(){ }}

      這種形式的單例模式,所有成員都是公開的,都可以通過singleton來訪問。這樣的缺點(diǎn)是單例中有一些輔助的方法并不希望暴露給使用者,如果使用者用了這些方法,然后在后面維護(hù)的時候,一些輔助方法被刪除,這樣會造成程序錯誤。

      如何避免這樣從的錯誤呢?

      包含私有成員的單例模式

      要怎么在類中創(chuàng)建私有成員呢,這通過需要閉包來進(jìn)行實(shí)現(xiàn),關(guān)于閉包的知識,本文不再贅述,大家可以自行Google。

      基本形式如下:

      var singleton = (function () { var privateVar = "private"; return { prop: "value", method: function () { console.log(privateVar); } } })();

      首先是一個自執(zhí)行的匿名函數(shù),在匿名函數(shù)中,聲明了一個變量privateVar,返回一個對象賦值給單例對象singleton。在匿名函數(shù)外部無法訪問到privateVar變量,它就是單例對象的私有變量,只能在函數(shù)內(nèi)部或通過暴露出來的方法去訪問這個私有變量。這種形式又被成為模塊模式。

      惰性實(shí)例化

      不管是直接字面量或者私有成員的單例模式,兩者都是在腳本加載時就被創(chuàng)建出來的單例,但是有時候,頁面可能永遠(yuǎn)也用不到這個單例對象,這樣會造成資源浪費(fèi)。對于這種情況,最佳的處理方式就是惰性加載,就是說在需要的時候才去真正實(shí)例化這個單例對象,如何實(shí)現(xiàn)呢?

      var singleton = (function () { function init() { var privateVar = "private"; return { prop: "value", method: function () { console.log(privateVar); } } } var instance = null; return { getInstance: function () { if (!instance) { instance = init(); } return instance; } } })();

      首先將創(chuàng)建單例對象的代碼封裝到init函數(shù)中,然后聲明一個私有變量instance表示單例對象的實(shí)例,公開一個方法getInstance來獲取單例對象。

      調(diào)用的時候就通過singleton.getInstance()來進(jìn)行調(diào)用,單例對象是在調(diào)用getInstance的時候才真正被創(chuàng)建。

      適用場合

      單例模式是JS中最常使用的設(shè)計(jì)模式,從增強(qiáng)模塊性和代碼組織性等方面來說,應(yīng)該盡可能的使用單例模式。它可以把相關(guān)代碼組織到一起便于維護(hù),對于大型項(xiàng)目,每個模塊惰性加載可以提高性能,隱藏實(shí)現(xiàn)細(xì)節(jié),暴露出常用的api。常見的類庫比如underscore,jQuery我們都可以將其理解為單例模式的應(yīng)用。

      結(jié)合實(shí)戰(zhàn)

      前面已經(jīng)講過,單例模式是最常用的設(shè)計(jì)模式之一,我們來舉個例子進(jìn)行說明,

      下面的代碼主要實(shí)現(xiàn)一個簡單的日期幫助類,通過單例模式實(shí)現(xiàn):

      基本的單例模式結(jié)構(gòu)

      var dateTimeHelper = { now: function () { return new Date(); }, format: function (date) { return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); } }; console.log(dateTimeHelper.now());

      這段代碼通過對象字面量實(shí)現(xiàn)單例模式,使用的時候直接調(diào)用方法即可。

      惰性加載實(shí)現(xiàn)單例模式

      var dateTimeHelper = (function () { function init() { return { now: function () { return new Date(); }, format: function (date) { return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); } } } var instance = null; return { getInstance: function () { if (!instance) { instance = init(); } return instance; } } })(); console.log(dateTimeHelper.getInstance().now())

      這就是惰性加載的單例模式。

      下面再來看幾個實(shí)例:

      實(shí)現(xiàn)1: 最簡單的對象字面量

      var singleton = { attr : 1, method : function(){ return this.attr; } }var t1 = singleton ;var t2 = singleton ;

      那么很顯然的, t1 === t2 。

      十分簡單,并且非常使用,不足之處在于沒有什么封裝性,所有的屬性方法都是暴露的。對于一些需要使用私有變量的情況就顯得心有余而力不足了。當(dāng)然在對于 this 的問題上也是有一定弊端的。

      實(shí)現(xiàn)2:構(gòu)造函數(shù)內(nèi)部判斷

      其實(shí)和最初的JS實(shí)現(xiàn)有點(diǎn)類似,不過是將對是否已經(jīng)存在該類的實(shí)例的判斷放入構(gòu)造函數(shù)內(nèi)部。

      function Construct(){ // 確保只有單例 if( Construct.unique !== undefined ){ return Construct.unique; } // 其他代碼 this.name = "NYF"; this.age="24"; Construct.unique = this;}var t1 = new Construct() ;var t2 = new Construct() ;

      那么也有的, t1 === t2 。

      也是非常簡單,無非就是提出一個屬性來做判斷,但是該方式也沒有安全性,一旦我在外部修改了Construct的unique屬性,那么單例模式也就被破壞了。

      實(shí)現(xiàn)3 : 閉包方式

      對于大著 靈活 牌子的JS來說,任何問題都能找到 n 種答案,只不過讓我自己去掂量孰優(yōu)孰劣而已,下面就簡單的舉幾個使用閉包實(shí)現(xiàn)單例模式的方法,無非也就是將創(chuàng)建了的單例緩存而已。

      var single = (function(){ var unique; function Construct(){ // ... 生成單例的構(gòu)造函數(shù)的代碼 } unique = new Constuct(); return unique;})();

      只要 每次講 var t1 = single; var t2 = single;即可。 與對象字面量方式類似。不過相對而言更安全一點(diǎn),當(dāng)然也不是絕對安全。

      如果希望會用調(diào)用 single() 方式來使用,那么也只需要將內(nèi)部的 return 改為

      return function(){ return unique; }

      以上方式也可以使用 new 的方式來進(jìn)行(形式主義的趕腳)。當(dāng)然這邊只是給了閉包的一種例子而已,也可以在 Construct 中判斷單例是否存在 等等。 各種方式在各個不同情況做好選著即可。

      總結(jié)

      單例模式的好處在于對代碼的組織作用,將相關(guān)的屬性和方法封裝在一個不會被多次實(shí)例化的對象中,讓代碼的維護(hù)和調(diào)試更加輕松。隱藏了實(shí)現(xiàn)細(xì)節(jié),可以防止被錯誤修改,還防止了全局命名空間的污染。另外可以通過惰性加載提高性能,減少不必要的內(nèi)存消耗。

    【javascript 單例模式詳解及簡單實(shí)例】相關(guān)文章:

    JavaScript中push(),join() 函數(shù)實(shí)例詳解09-05

    常用的JavaScript模式09-22

    JavaScript fontcolor方法入門實(shí)例07-07

    javascript閉包的定義及應(yīng)用實(shí)例分析08-25

    詳解JavaScript中的splice()使用方法08-20

    現(xiàn)代采購模式詳解12-02

    Javascript中arguments對象的詳解和使用方法08-20

    Java文件解壓縮實(shí)例詳解201607-26

    對javascript的理解08-08

    Javascript的this用法簡述08-15

    主站蜘蛛池模板: 自拍中文精品无码| 尤物TV国产精品看片在线| 精品国产青草久久久久福利| 老司机亚洲精品影院无码| 欧美日激情日韩精品| 亚洲AV日韩精品久久久久久| 日韩欧美精品不卡| 亚洲中文字幕久久精品无码APP | 欧美国产日韩精品| 亚洲级αV无码毛片久久精品| 99爱在线视频这里只有精品| 久久久久女人精品毛片| 久久久精品视频免费观看| 国产精品视频网站| 中文字幕在线精品视频入口一区| 91精品国产成人网在线观看| 久久九九精品99国产精品| 蜜桃麻豆www久久国产精品| 欧美极品欧美精品欧美视频| 欧美jizzhd精品欧美| 亚洲av午夜精品一区二区三区| 国产福利精品视频自拍 | 精品久久久久中文字| 精品视频在线免费观看| 日韩精品无码一本二本三本| 三级国产精品| 国产精品无码专区在线观看| 国产在线精品网址你懂的| 久久99精品国产麻豆| 中文无码精品一区二区三区| 久久精品国产亚洲av瑜伽| 国产精品乱码一区二区三区| 欧美精品888| 精品亚洲综合在线第一区| 3D动漫精品一区二区三区| 久久久久人妻一区精品性色av| 永久无码精品三区在线4| 亚洲欧美国产精品专区久久| 乱人伦人妻精品一区二区| 国产亚洲精品高清在线| 国产精品麻豆VA在线播放|