JS 設(shè)計模式之:單例模式定義與實(shí)現(xiàn)方法淺析
本文實(shí)例講述了JS 設(shè)計模式之:單例模式定義與實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:
良好的設(shè)計模式可以顯著提高代碼的可讀性,降低復(fù)雜度和維護(hù)成本。筆者打算通過幾篇文章通俗地講一講常見的或者實(shí)用的設(shè)計模式。
今天先從最簡單的一個入手:單例模式。
文中的示例代碼會使用 ES6 語法,盡量簡化不必要的細(xì)節(jié)
概念
單例模式(Singleton)屬于創(chuàng)建型的設(shè)計模式,它限制我們只能創(chuàng)建單一對象或者某個類的單一實(shí)例。
通常情況下,使用該模式是為了控制整個應(yīng)用程序的狀態(tài)。在日常的開發(fā)中,我們遇到的單例模式可能有:Vuex 中的 Store,Vue 的根實(shí)例,任何導(dǎo)出單個對象的 ES6 模塊等。
字面量寫法
最簡單的單例其實(shí)就像下面這樣:
const cat = { name: 'mi', age: 4 }
了解 const
語法的小伙伴都知道,這只喵是不能被重新賦值的,但是它里面的屬性其實(shí)是可變的。
如果想要一個不可變的單例對象:
const cat = { name: 'mi', age: 4 } Object.freeze(cat);
這樣就不能新增或修改這只喵上的任何屬性,它變成了 冰凍喵~
如果是在模塊中使用,上面的寫法并不會污染全局作用域,但是直接生成一個固定的對象缺少了一些靈活性。
常用寫法
相對而言,使用類或工廠方法來實(shí)現(xiàn)單例更加常用。假設(shè)我們有一個叫作 Logger
的類,它具有和 Console
相同的 API。
類單例
類的單例寫法非常常用,如果我們想要這么使用它:
const logger = new Logger(); logger.log('msg'); // 這里大概寫了 1000 行代碼 const logger2 = new Logger(); logger.log('new msg'); logger === logger2; // true
即盡管 new
了多次 Logger
,它返回的都是同一個實(shí)例。
下面直接看最實(shí)用的實(shí)現(xiàn)方式:
class Logger { constructor () { if (!Logger._singleton) { Logger._singleton = this; } return Logger._singleton; } log (...args) { console.log(...args); } } export default Logger;
上面的方式將單例對象存儲在了構(gòu)造器上,這樣的話不管 new Logger
多少次,返回的都是同一個 Logger 實(shí)例了。
這里有一個細(xì)節(jié)需要注意,即 new
關(guān)鍵字后面的構(gòu)造函數(shù)如果顯式返回一個對象,new
表達(dá)式就會返回該對象。
具體可參見 《你不知道的 JavaScript (上卷)》中的 new 綁定 相關(guān)章節(jié)。
工廠單例
如果不喜歡用 new 關(guān)鍵字,可以使用工廠方法返回單例對象。
let logger = null class Logger { log (...args) { console.log(...args); } } function createLogger() { if (!logger) { logger = new Logger(); } return logger; } export default createLogger;
上面的代碼相當(dāng)于在模塊內(nèi)部緩存了 logger 實(shí)例,然后導(dǎo)出了一個工廠方法。這種寫法在模塊化代碼中比較常見,工廠方法也可以接收參數(shù)用來初始化單例對象。
今天的內(nèi)容比較好理解,其中的單例寫法也是筆者常用的方法。
下一篇我們再具體講講工廠模式的應(yīng)用~
參考內(nèi)容
- 《JavaScript 設(shè)計模式》
- 《JavaScript 面向?qū)ο缶幊讨改稀?/li>
- 《你不知道的 JavaScript (上卷)》
- Working with Singletons in JavaScript
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
相關(guān)文章
基于JS實(shí)現(xiàn)操作成功之后自動跳轉(zhuǎn)頁面
這篇文章主要介紹了基于JS實(shí)現(xiàn)操作成功之后自動跳轉(zhuǎn)頁面的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09JavaScript+html5 canvas制作的圓中圓效果實(shí)例
這篇文章主要介紹了JavaScript+html5 canvas制作的圓中圓效果,結(jié)合完整實(shí)例形式分析了基于JavaScript與html5 canvas技術(shù)實(shí)現(xiàn)的圖形繪制與顏色隨機(jī)填充技巧,需要的朋友可以參考下2016-01-01用javascript獲取textarea中的光標(biāo)位置
Javascript一向以他的靈活隨意而著稱,這也使得它的功能可以非常的強(qiáng)大,而由于沒有比較好的調(diào)試工具,又使得它使用起來困難重重,尤其使對于一些初學(xué)者,更是感覺到無從下手。今天探討的問題是用javascript獲取textarea中光標(biāo)的位置。2008-05-05