成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐系列之單例模式

Airy / 3386人閱讀

摘要:本系列為設(shè)計(jì)模式與開發(fā)實(shí)踐作者曾探學(xué)習(xí)總結(jié),如想深入了解,請(qǐng)支持作者原版單例模式實(shí)現(xiàn)單例模式單例模式的定義是保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。

本系列為《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》(作者:曾探)學(xué)習(xí)總結(jié),如想深入了解,請(qǐng)支持作者原版

單例模式 實(shí)現(xiàn)單例模式

單例模式的定義是:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
單例模式是一種常用的模式,有一些對(duì)象我們往往只需要一個(gè),比如登錄窗口,這個(gè)窗口是唯一的,無論我們點(diǎn)擊多少次登錄按鈕,這個(gè)窗口只會(huì)被創(chuàng)建一次,那么這個(gè)窗口就適合用單例模式來創(chuàng)建。

要實(shí)現(xiàn)一個(gè)標(biāo)準(zhǔn)的單例模式并不復(fù)雜,無非是用一個(gè)變量來標(biāo)志當(dāng)前是否已經(jīng)為某個(gè)類創(chuàng)建過對(duì)象,如果是,則在下一次獲取該類的實(shí)例時(shí),直接返回之前創(chuàng)建的對(duì)象。代碼如下:

var Singleton=function(name){
    this.name=name;
    this.instance=null;
};
Singleton.prototype.getName=function(){
    alert(this.name);
};
Singleton.getInstance=function(){
    if(!this.instance){
        this.instance=new Singleton(name);
    }
    return this.instance;
};
var a=Singleton.getInstance("sven1");
var b=Singleton.getInstance("sven2");

alert(a===b);//true

或者

var Singleton=function(name){
    this.name=name;
};
Singleton.prototype.getName=function(){
    alert(this.name);
};
Singleton.getInstance=(function(){
    var instance=null;
    return function(name){
        if(!instance){
            instance=new Singleton(name);
        }
        return instance;
    }
})();

我們通過Singleton.getInstance來獲取Singleton類的唯一對(duì)象,這種方式相對(duì)簡(jiǎn)單,但是不透明。跟以往通過new XXX的方式獲取對(duì)象不同,這里偏要使用Singleton.getInstance來獲取對(duì)象,所以這段代碼的意義并不大。

透明的單例模式

我們現(xiàn)在的目標(biāo)是實(shí)現(xiàn)一個(gè)透明的單例類。

var CreateDiv = (function() {
    
    var instance;
    
    var CreateDiv = function(html) {
        if (instance) {
            return instance;
        }
        this.html = html;
        this.init();
        return instance = this;
    };
    CreateDiv.prototype.init = function() {
        var div = document.createElement("div");
        div.innerHtml = this.html;
        document.body.appendChild(div);
    };
    return CreateDiv;
})()

var a = new CreateDiv("sven1");
var b = new CreateDiv("sven2");
alert(a===b);//true

雖然現(xiàn)在完成了一個(gè)透明的單例類的編寫,但它同樣有一些缺點(diǎn)。為了把instance封裝起來,我們使用了自執(zhí)行的匿名函數(shù)和閉包,并且讓這個(gè)匿名函數(shù)返回真正的Singleton構(gòu)造方法,這增加了一些程序的復(fù)雜度,閱讀起來也不是很舒服。
假設(shè)我們某天需要讓這個(gè)單例類變成一個(gè)普通的類,即可以產(chǎn)生多個(gè)實(shí)例,那我們必須改寫CreateDiv構(gòu)造函數(shù),這種修改會(huì)帶來很多不必要的麻煩。

用代理實(shí)現(xiàn)單例模式

我們首先創(chuàng)建一個(gè)普通的CreateDiv類:

var CreateDiv = function(html) {
  this.html = html;
  this.init();
};
CreateDiv.prototype.init = function() {
  var div = document.createElement("div");
  div.innerHtml = this.html;
  document.body.appendChild(div);
};

接下來引入代理類ProxySingletonCreate:

var ProxySingletonCreate = (function() {
  var instance;
  return function(html) {
    if (!instance) {
      instance = new CreateDiv(html);
    }
    return instance;
  }
})();

var a = new ProxySingletonCreate("sven1");
var b = new ProxySingletonCreate("sven2");
console.log(a === b);

這樣一來,CreateDivProxySingletonCreate組合起來,實(shí)現(xiàn)了單例模式的效果。

JavaScript中的單例模式

前面提到的幾種單例模式的實(shí)現(xiàn),更多的是接近傳統(tǒng)面向?qū)ο笳Z言中的實(shí)現(xiàn),單例對(duì)象從中創(chuàng)建而來。但JavaScript其實(shí)是一門無類的語言,所以生搬單例模式的概念并無意義。
單例模式的核心是:確保只有一個(gè)實(shí)例,并提供全局訪問
全局變量不是單例模式,但在實(shí)際應(yīng)用中,我們經(jīng)常會(huì)把全局變量當(dāng)成單例來使用。
例如:

var a = {};

全局變量可以滿足上述的兩個(gè)條件,但卻存在許多問題:它很容易造成命名空間污染。作為普通的開發(fā)者,我們有必要減少全局變量的使用,一下幾種方式可以相對(duì)降低全局變量帶來的命名污染。

使用命名空間

最簡(jiǎn)單的方法依然是使用對(duì)象字面量方式:

var namespace1={
    a:function(){
    },
    b:function(){
    }
};

我們還可以動(dòng)態(tài)的創(chuàng)建命名空間:

var myApp = {};
myApp.namespace = function(name) {
  var parts = name.split(".");
  var current = myApp;
  for (var i in parts) {
    if (!current[parts[i]]) {
      current[parts[i]] = {};
    }
    current = current[parts[i]];
  }
};

myApp.namespace("event");
myApp.namespace("dom.style");

console.log(myApp);
使用閉包封裝私有變量
var user=(function(){
    var _name="sven",_age=29;
    return {
        getUserInfo:function(){
            return _name+"_"+_age;
        }
    }
})();
惰性單例

惰性單例指的是在需要的時(shí)候才創(chuàng)建對(duì)象實(shí)例。惰性單例是單例模式的重點(diǎn),這種技術(shù)在實(shí)際開發(fā)中非常有用。
我們先抽取出一個(gè)管理單例的邏輯對(duì)象:

var getSingle=function(fn){
    var result;
    return function(){
        return result||(result=fn.apply(this.arguments));
    }
};

創(chuàng)建對(duì)象的方法fn被當(dāng)做參數(shù)傳入getSingle。

var getSingle = function(fn) {
  var result;
  return function() {
    return result || (result = fn.apply(this.arguments));
  };
};

var createLoginLayer = function() {
  var div = document.createElement("div");
  div.innerHTML = "我是登錄窗";
  div.style.width = "100px";
  div.style.height = "100px";
  div.style.background = "red";
  document.body.appendChild(div);
  return div;
};

aa = getSingle(createLoginLayer);
aa();

result變量因?yàn)樯碓?b>閉包中,永遠(yuǎn)不會(huì)被銷毀。在將來的請(qǐng)求中,如果result已經(jīng)被賦值,那么他將返回這個(gè)值。
以下是演示地址:

惰性單例演示地址
其他演示地址

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78844.html

相關(guān)文章

  • javascript設(shè)計(jì)模式開發(fā)實(shí)踐全書深度解析(一)單例模式

    摘要:所以程序在引入文件的時(shí)候用了單例模式,一個(gè)文件實(shí)例化一次,這種做法無疑是好的,但是也容易引起。在我們平時(shí)的開發(fā)過程中,可以借鑒這兩種方式去緩存變量,節(jié)點(diǎn)等。 這一章作者講了一個(gè)例子,就是在用單例模式生成一個(gè)dom節(jié)點(diǎn),還要做到只有訪問的時(shí)候才創(chuàng)建,后續(xù)訪問直接用前面創(chuàng)建的。那么實(shí)際開發(fā)中我們會(huì)用到這個(gè)模式嗎?現(xiàn)在我們基本都是用vue,react,angular開發(fā),不太會(huì)直接去操作do...

    xioqua 評(píng)論0 收藏0
  • 設(shè)計(jì)模式單例模式

    摘要:最佳實(shí)踐使用代理方式實(shí)現(xiàn)單例模式,使用一個(gè)代理函數(shù)來實(shí)現(xiàn)實(shí)單例例化原生的代碼摘自設(shè)計(jì)模式與開發(fā)實(shí)踐下來代理類測(cè)試函數(shù)返回版的用實(shí)現(xiàn)的單例模式代碼已創(chuàng)建張三李四返回 說明:只要實(shí)例化一次,超過一次的實(shí)例化過程會(huì)返回之前實(shí)例化的結(jié)果,而不會(huì)在內(nèi)存中再次寫入新的實(shí)例對(duì)象。----類似于once。 需要遵守的原則:?jiǎn)我宦氊?zé)的原則,每一個(gè)類或者函數(shù)只負(fù)責(zé)一個(gè)功能。 最佳實(shí)踐:使用代理方式實(shí)現(xiàn)單例...

    whinc 評(píng)論0 收藏0
  • 程序語言

    摘要:一面應(yīng)該還問了其他內(nèi)容,但是兩次面試多線程面試問題和答案采訪中,我們通常會(huì)遇到兩個(gè)主題采集問題和多線程面試問題。多線程是關(guān)于并發(fā)和線程的。我們正在共享重要的多線程面試問題和答案。。 2016 年末,騰訊,百度,華為,搜狗和滴滴面試題匯總 2016 年未,騰訊,百度,華為,搜狗和滴滴面試題匯總 【碼農(nóng)每日一題】Java 內(nèi)部類(Part 2)相關(guān)面試題 關(guān)注一下嘛,又不讓你背鍋!問:Ja...

    mtunique 評(píng)論0 收藏0
  • 程序語言

    摘要:一面應(yīng)該還問了其他內(nèi)容,但是兩次面試多線程面試問題和答案采訪中,我們通常會(huì)遇到兩個(gè)主題采集問題和多線程面試問題。多線程是關(guān)于并發(fā)和線程的。我們正在共享重要的多線程面試問題和答案。。 2016 年末,騰訊,百度,華為,搜狗和滴滴面試題匯總 2016 年未,騰訊,百度,華為,搜狗和滴滴面試題匯總 【碼農(nóng)每日一題】Java 內(nèi)部類(Part 2)相關(guān)面試題 關(guān)注一下嘛,又不讓你背鍋!問:Ja...

    stefan 評(píng)論0 收藏0
  • JS或Jquery

    摘要:大潮來襲前端開發(fā)能做些什么去年谷歌和火狐針對(duì)提出了的標(biāo)準(zhǔn),顧名思義,即的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁,新的標(biāo)準(zhǔn)讓我們可以使用語言來開發(fā)。 VR 大潮來襲 --- 前端開發(fā)能做些什么 去年谷歌和火狐針對(duì) WebVR 提出了 WebVR API 的標(biāo)準(zhǔn),顧名思義,WebVR 即 web + VR 的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁,新的 API 標(biāo)準(zhǔn)讓我們可以使用 ...

    CatalpaFlat 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<