亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JavaScript 設(shè)計(jì)模式(一):?jiǎn)卫J?

xialong / 1885人閱讀

摘要:停更許久,近期計(jì)劃更新設(shè)計(jì)模式系列。單例模式是創(chuàng)建型設(shè)計(jì)模式的一種。雖然它不是正規(guī)的單例模式,但不可否認(rèn)確實(shí)具備類單例模式的特點(diǎn)。適用場(chǎng)景單例模式的特點(diǎn),意圖解決維護(hù)一個(gè)全局實(shí)例對(duì)象。

停更許久,近期計(jì)劃更新:設(shè)計(jì)模式系列。

單例模式:限制類實(shí)例化次數(shù)只能一次,一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。

單例模式是創(chuàng)建型設(shè)計(jì)模式的一種。針對(duì)全局僅需一個(gè)對(duì)象的場(chǎng)景,如線程池、全局緩存、window 對(duì)象等。

模式特點(diǎn)

類只有一個(gè)實(shí)例

全局可訪問該實(shí)例

自行實(shí)例化(主動(dòng)實(shí)例化)

可推遲初始化,即延遲執(zhí)行(與靜態(tài)類/對(duì)象的區(qū)別)

JavaScript 是一門非正規(guī)面向?qū)ο蟮恼Z(yǔ)言,并沒有類的定義。而單例模式要求一個(gè) “唯一” 和 “全局訪問” 的對(duì)象,在 JavaScript 中類似全局對(duì)象,剛好滿足單例模式的兩個(gè)特點(diǎn):“唯一” 和 “可全局訪問”。雖然它不是正規(guī)的單例模式,但不可否認(rèn)確實(shí)具備類單例模式的特點(diǎn)。

// 全局對(duì)象
var globaObj = {};

使用全局變量會(huì)有以下問題:

命名空間污染(變量名沖突)

維護(hù)時(shí)不方便管控(容易不小心覆蓋)

全局變量問題折中的應(yīng)對(duì)方案:

使用命名空間

閉包封裝私有變量(利用函數(shù)作用域)

ES6的 const/symbol

雖然全局變量可以實(shí)現(xiàn)單例,但因其自身的問題,不建議在實(shí)際項(xiàng)目中將其作為單例模式的應(yīng)用,特別是中大型項(xiàng)目的應(yīng)用中,全局變量的維護(hù)該是考慮的成本。

模式實(shí)現(xiàn)
實(shí)現(xiàn)方式:使用一個(gè)變量存儲(chǔ)類實(shí)例對(duì)象(值初始為 null/undefined )。進(jìn)行類實(shí)例化時(shí),判斷類實(shí)例對(duì)象是否存在,存在則返回該實(shí)例,不存在則創(chuàng)建類實(shí)例后返回。多次調(diào)用類生成實(shí)例方法,返回同一個(gè)實(shí)例對(duì)象。
“簡(jiǎn)單版” 單例模式:
let Singleton = function(name) {
    this.name = name;
    this.instance = null;
}

Singleton.prototype.getName = function() {
    console.log(this.name);
}

Singleton.getInstance = function(name) {
    if (this.instance) {
        return this.instance;
    }
    return this.instance = new Singleton(name);
}

let Winner = Singleton.getInstance("Winner");
let Looser = Singleton.getInstance("Looser");

console.log(Winner === Looser); // true
console.log(Winner.getName());  // "Winner"
console.log(Looser.getName());  // "Winner"

代碼中定義了一個(gè) Singleton 函數(shù),函數(shù)在 JavaScript 中是“一等公民“,可以為其定義屬性方法。因此我們可以在函數(shù) Singleton 中定義一個(gè) getInstance() 方法來(lái)管控單例,并創(chuàng)建返回類實(shí)例對(duì)象,而不是通過(guò)傳統(tǒng)的 new 操作符來(lái)創(chuàng)建類實(shí)例對(duì)象。

this.instance 存儲(chǔ)創(chuàng)建的實(shí)例對(duì)象,每次接收到創(chuàng)建實(shí)例對(duì)象時(shí),判斷 this.instance 是否有實(shí)例對(duì)象,有則返回,沒有則創(chuàng)建并更新 this.instance 值,因此無(wú)論調(diào)用多少次 getInstance(),最終都只會(huì)返回同一個(gè) Singleton 類實(shí)例對(duì)象。

存在問題:

不夠“透明”,無(wú)法使用 new 來(lái)進(jìn)行類實(shí)例化,需約束該類實(shí)例化的調(diào)用方式: Singleton.getInstance(...);

管理單例的操作,與對(duì)象創(chuàng)建的操作,功能代碼耦合在一起,不符合 “單一職責(zé)原則”

“透明版” 單例模式:

實(shí)現(xiàn) “透明版” 單例模式,意圖解決:統(tǒng)一使用 new 操作符來(lái)獲取單例對(duì)象, 而不是 Singleton.getInstance(...)。

let CreateSingleton = (function(){
    let instance;
    return function(name) {
        if (instance) {
            return instance;
        }
        this.name = name;
        return instance = this;
    }
})();
CreateSingleton.prototype.getName = function() {
    console.log(this.name);
}

let Winner = new CreateSingleton("Winner");
let Looser = new CreateSingleton("Looser");

console.log(Winner === Looser); // true
console.log(Winner.getName());  // "Winner"
console.log(Looser.getName());  // "Winner"

“透明版”單例模式解決了不夠“透明”的問題,我們又可以使用 new 操作符來(lái)創(chuàng)建實(shí)例對(duì)象。

“代理版“ 單例模式:

通過(guò)“代理”的形式,意圖解決:將管理單例操作,與對(duì)象創(chuàng)建操作進(jìn)行拆分,實(shí)現(xiàn)更小的粒度劃分,符合“單一職責(zé)原則”

let ProxyCreateSingleton = (function(){
    let instance;
    return function(name) {
        // 代理函數(shù)僅作管控單例
        if (instance) {
            return instance;
        }
        return instance = new Singleton(name);
    }
})();

// 獨(dú)立的Singleton類,處理對(duì)象實(shí)例
let Singleton = function(name) {
    this.name = name;
}
Singleton.prototype.getName = function() {
    console.log(this.name);
}

let Winner = new PeozyCreateSingleton("Winner");
let Looser = new PeozyCreateSingleton("Looser");

console.log(Winner === Looser); // true
console.log(Winner.getName());  // "Winner"
console.log(Looser.getName());  // "Winner"
惰性單例模式

惰性單例,意圖解決:需要時(shí)才創(chuàng)建類實(shí)例對(duì)象。對(duì)于懶加載的性能優(yōu)化,想必前端開發(fā)者并不陌生。惰性單例也是解決 “按需加載” 的問題。

需求:頁(yè)面彈窗提示,多次調(diào)用,都只有一個(gè)彈窗對(duì)象,只是展示信息內(nèi)容不同。

開發(fā)這樣一個(gè)全局彈窗對(duì)象,我們可以應(yīng)用單例模式。為了提升它的性能,我們可以讓它在我們需要調(diào)用時(shí)再去生成實(shí)例,創(chuàng)建 DOM 節(jié)點(diǎn)。

let getSingleton = function(fn) {
    var result;
    return function() {
        return result || (result = fn.apply(this, arguments)); // 確定this上下文并傳遞參數(shù)
    }
}
let createAlertMessage = function(html) {
    var div = document.createElement("div");
    div.innerHTML = html;
    div.style.display = "none";
    document.body.appendChild(div);
    return div;
}

let createSingleAlertMessage = getSingleton(createAlertMessage);
document.body.addEventListener("click", function(){
    // 多次點(diǎn)擊只會(huì)產(chǎn)生一個(gè)彈窗
    let alertMessage = createSingleAlertMessage("您的知識(shí)需要付費(fèi)充值!");
    alertMessage.style.display = "block";
})

代碼中演示是一個(gè)通用的 “惰性單例” 的創(chuàng)建方式,如果還需要 createLoginLayer 登錄框, createFrame Frame框, 都可以調(diào)用 getSingleton(...) 生成對(duì)應(yīng)實(shí)例對(duì)象的方法。

適用場(chǎng)景

“單例模式的特點(diǎn),意圖解決:維護(hù)一個(gè)全局實(shí)例對(duì)象?!?/strong>

引用第三方庫(kù)(多次引用只會(huì)使用一個(gè)庫(kù)引用,如 jQuery)

彈窗(登錄框,信息提升框)

購(gòu)物車 (一個(gè)用戶只有一個(gè)購(gòu)物車)

全局態(tài)管理 store (Vuex / Redux)

項(xiàng)目中引入第三方庫(kù)時(shí),重復(fù)多次加載庫(kù)文件時(shí),全局只會(huì)實(shí)例化一個(gè)庫(kù)對(duì)象,如 jQuery,lodashmoment ..., 其實(shí)它們的實(shí)現(xiàn)理念也是單例模式應(yīng)用的一種:

// 引入代碼庫(kù) libs(庫(kù)別名)
if (window.libs != null) {
  return window.libs;    // 直接返回
} else {
  window.libs = "...";   // 初始化
}
優(yōu)缺點(diǎn)

優(yōu)點(diǎn):適用于單一對(duì)象,只生成一個(gè)對(duì)象實(shí)例,避免頻繁創(chuàng)建和銷毀實(shí)例,減少內(nèi)存占用。

缺點(diǎn):不適用動(dòng)態(tài)擴(kuò)展對(duì)象,或需創(chuàng)建多個(gè)相似對(duì)象的場(chǎng)景。

TIPS: 多線程編程語(yǔ)言中,單例模式會(huì)涉及同步鎖的問題。而 JavaScript 是單線程的編程語(yǔ)言,暫可忽略該問題。

參考文章

《JavaScript 設(shè)計(jì)模式》

《JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)踐》

《JavaScript 設(shè)計(jì)模式系統(tǒng)講解與應(yīng)用》

本文首發(fā)Github,期待Star!
https://github.com/ZengLingYong/blog

作者:以樂之名
本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請(qǐng)指明出處。

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

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

相關(guān)文章

  • JavaScript設(shè)計(jì)模式單例模式

    摘要:此時(shí)我們創(chuàng)建的對(duì)象內(nèi)保存靜態(tài)變量通過(guò)取值器訪問,最后將這個(gè)對(duì)象作為一個(gè)單例放在全局空間里面作為靜態(tài)變量單例對(duì)象供他人使用。 單例模式 又被稱為單體模式,是只允許實(shí)例化一次的對(duì)象類。有時(shí)我們也用一個(gè)對(duì)象來(lái)規(guī)劃一個(gè)命名空間,井井有條的管理對(duì)象上面的屬性和方法。 傳統(tǒng)的面向?qū)ο笳Z(yǔ)言中單例模式的實(shí)現(xiàn),均是單例對(duì)象從類中創(chuàng)建而來(lái),在以類為中心的語(yǔ)言中,這是很常見的做法。如果需要某個(gè)對(duì)象,就必須先...

    zhaot 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐 | 04 - 單例模式

    摘要:觀察構(gòu)造函數(shù)的代碼,該構(gòu)造函數(shù)實(shí)際上負(fù)責(zé)了兩件事情第一是創(chuàng)建對(duì)象和執(zhí)行初始化方法,第二是保證只有一個(gè)對(duì)象。惰性單例在實(shí)際開發(fā)中非常有用,是單例模式的重點(diǎn)。 單例模式 單例模式的定義是: 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。 單例模式是一種常用的模式,有一些對(duì)象我們往往只需要一個(gè),比如線程池、全局緩存、瀏覽器的window對(duì)象等。例如,當(dāng)我們點(diǎn)擊登錄按鈕時(shí),頁(yè)面會(huì)彈出一...

    awkj 評(píng)論0 收藏0
  • 再遇設(shè)計(jì)模式JavaScript

    摘要:在面向?qū)ο蟮恼Z(yǔ)言中,比如,等,單例模式通常是定義類時(shí)將構(gòu)造函數(shù)設(shè)為,保證對(duì)象不能在外部被出來(lái),同時(shí)給類定義一個(gè)靜態(tài)的方法,用來(lái)獲取或者創(chuàng)建這個(gè)唯一的實(shí)例。 萬(wàn)事開頭難,作為正經(jīng)歷菜鳥賽季的前端player,已經(jīng)忘記第一次告訴自己要寫一些東西出來(lái)是多久以的事情了。。。如果,你也和我一樣,那就像我一樣,從現(xiàn)在開始,從看到這篇文章開始,打開電腦,敲下你的第一篇文章(或者任何形式的文字)吧。 ...

    Clect 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式-第部分:單例模式、組合模式和外觀模式

    摘要:但是,這并不是采用單例的唯一原因。使用命名空間單例模式也被稱為模塊設(shè)計(jì)模式。函數(shù)內(nèi)部聲明了一些局部函數(shù)和或變量。緊隨函數(shù)聲明放置即可立即執(zhí)行外部函數(shù),并將所得的對(duì)象文字費(fèi)賠給變量。 JavaScript設(shè)計(jì)模式-第一部分:?jiǎn)卫J?、組合模式和外觀模式 設(shè)計(jì)模式是一些可靠的編程方式,有助于保證代碼更加易于維護(hù)、擴(kuò)展及分離,所有設(shè)計(jì)模式在創(chuàng)建大型JavaScript應(yīng)用程序時(shí)均不可或缺 單...

    betacat 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式學(xué)習(xí)—單例模式

    摘要:什么是單例模式簡(jiǎn)單點(diǎn)來(lái)說(shuō),單例模式就是確保某個(gè)類只有一個(gè)實(shí)例,并且最好只被創(chuàng)建過(guò)一次。對(duì)計(jì)算機(jī)來(lái)說(shuō),像打印機(jī),線程池都是經(jīng)典的單例模式。 什么是單例模式 簡(jiǎn)單點(diǎn)來(lái)說(shuō),單例模式就是確保某個(gè)類只有一個(gè)實(shí)例,并且最好只被創(chuàng)建過(guò)一次。對(duì)計(jì)算機(jī)來(lái)說(shuō),像打印機(jī),線程池都是經(jīng)典的單例模式。對(duì)于JavaScript所處的前端環(huán)境來(lái)說(shuō),像登錄懸浮框,在整個(gè)頁(yè)面中只會(huì)有一個(gè),無(wú)論用戶點(diǎn)擊多少次,只會(huì)被創(chuàng)建...

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

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

0條評(píng)論

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