摘要:但是如何在對構(gòu)造函數(shù)使用操作符創(chuàng)建多個對象的時候僅獲取一個單例對象呢。單例的實例引用單例構(gòu)造函數(shù)單例私有屬性和方法暴露出來的對象改進之前在構(gòu)造函數(shù)中重寫自身會丟失所有在初始定義和重定義之間添加到其中的屬性。
1. 單例模式
單例模式 (Singleton) 的實現(xiàn)在于保證一個特定類只有一個實例,第二次使用同一個類創(chuàng)建新對象的時候,應(yīng)該得到與第一次創(chuàng)建對象完全相同的對象。
當創(chuàng)建一個新對象時,實際上沒有其他對象與其類似,因為新對象已經(jīng)是單例了 {a:1} === {a:1} // false 。
但是如何在對構(gòu)造函數(shù)使用 new 操作符創(chuàng)建多個對象的時候僅獲取一個單例對象呢。
2. 靜態(tài)屬性中的實例在構(gòu)造函數(shù)的靜態(tài)屬性中緩存該實例,缺點在于 instance 屬性是公開可訪問的屬性,在外部代碼中可能會修改該屬性。
function Universe() { if (typeof Universe.instance === "object") { // 判斷是否已經(jīng)有單例了 return Universe.instance } Universe.instance = this return this } var uni1 = new Universe() var uni2 = new Universe() uni1 === uni2 // true3. 閉包中的實例
可以把實例封裝在閉包中,這樣可以保證該實例的私有性并且保證該實例不會在構(gòu)造函數(shù)之外被修改,代價是帶來了額外的閉包開銷。
function Universe() { var instance = this Universe = function() { // 重寫構(gòu)造函數(shù) return instance } } var uni1 = new Universe() var uni2 = new Universe() uni1 === uni2 // true
當?shù)谝淮握{(diào)用構(gòu)造函數(shù)時,它正常返回 this ,然后在以后調(diào)用時,它將會執(zhí)行重寫構(gòu)造函數(shù),這個構(gòu)造函數(shù)通過閉包訪問了私有 instance 變量,并且簡單的返回了該 instance。
4. 惰性單例有時候?qū)τ趩卫龑ο笮枰舆t創(chuàng)建,所以在單例中還存在一種延遲創(chuàng)建的形式,也有人稱之為惰性創(chuàng)建。
const LazySingle = (function() { let _instance // 單例的實例引用 function Single() { // 單例構(gòu)造函數(shù) const desc = "單例" // 私有屬性和方法 return { // 暴露出來的對象 publicMethod: function() {console.log(desc)}, publickProperty: "1.0" } } return function() { return _instance || (_instance = Single()) } })() console.log(LazySingle()===lazySingle()) // true console.log(LazySingle().publickProperty) // 1.05. 改進
之前在構(gòu)造函數(shù)中重寫自身會丟失所有在初始定義和重定義之間添加到其中的屬性。在這種情況下,任何添加到 Universe() 的原型中的對象都不會存在指向由原始實現(xiàn)所創(chuàng)建實例的活動鏈接:
function Universe() { var instance = this Universe = function() { return instance } } Universe.prototype.nothing = true var uni1 = new Universe() Universe.prototype.enthing = true var uni2 = new Universe() console.log(uni1 === uni2) // true uni1.nothing // true uni2.nothing // true uni1.enthing // undefined uni2.enthing // undefined uni1.constructor.name // "Universe" uni1.constructor === Universe // false
之所以 uni1.constructor 不再與 Universe() 相同,是因為uni1.constructor仍然指向原始的構(gòu)造函數(shù),而不是重定義之后的那個構(gòu)造函數(shù)。
可以通過一些調(diào)整實現(xiàn)原型和構(gòu)造函數(shù)指針按照預(yù)期的那樣運行:
function Universe() { var instance Universe = function Universe() { return instance } Universe.prototype = this // 保留原型屬性 instance = new Universe() instance.constructor = Universe // 重置構(gòu)造函數(shù)指針 instance.start_time = 0 // 一些屬性 instance.big = "yeah" return instance } Universe.prototype.nothing = true var uni1 = new Universe() Universe.prototype.enthing = true var uni2 = new Universe() console.log(uni1 === uni2) // true uni1.nothing & uni2.nothing & uni1.enthing & uni2.enthing // true uni1.constructor.name // "Universe" uni1.constructor === Universe // true uni1.big // "yeah" uni2.big // "yeah"
本文是系列文章,可以相互參考印證,共同進步~
JS 抽象工廠模式
JS 工廠模式
JS 建造者模式
JS 原型模式
JS 單例模式
JS 回調(diào)模式
JS 外觀模式
JS 適配器模式
JS 利用高階函數(shù)實現(xiàn)函數(shù)緩存(備忘模式)
JS 狀態(tài)模式
JS 橋接模式
JS 觀察者模式
網(wǎng)上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學習過程中的總結(jié),如果發(fā)現(xiàn)錯誤,歡迎留言指出~
參考:
《JavaScript模式》 P143
《Javascript 設(shè)計模式》 - 張榮銘
設(shè)計模式之單例模式
PS:歡迎大家關(guān)注我的公眾號【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,長按識別下面二維碼即可加我好友,備注加群,我拉你入群~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/92144.html
摘要:文章系列設(shè)計模式單例模式設(shè)計模式策略模式設(shè)計模式代理模式概念單例模式的定義是保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。在開發(fā)中,單例模式的用途同樣非常廣泛。 前言 本系列文章主要根據(jù)《JavaScript設(shè)計模式與開發(fā)實踐》整理而來,其中會加入了一些自己的思考。希望對大家有所幫助。 文章系列 js設(shè)計模式--單例模式 js設(shè)計模式--策略模式 js設(shè)計模式--代理模式 概念...
摘要:什么是設(shè)計模式設(shè)計模式是一種能夠被反復(fù)使用,符合面向?qū)ο筇匦缘拇a設(shè)計經(jīng)驗的總結(jié),合理的使用設(shè)計模式能夠讓你得代碼更容易維護和可靠設(shè)計模式的類型共分為創(chuàng)建型模式,結(jié)構(gòu)型模式,行為型模式三種創(chuàng)建型模式創(chuàng)建型模式是對一個類的實例化過程進行了抽象 什么是設(shè)計模式 設(shè)計模式是一種能夠被反復(fù)使用,符合面向?qū)ο筇匦缘拇a設(shè)計經(jīng)驗的總結(jié),合理的使用設(shè)計模式能夠讓你得代碼更容易維護和可靠設(shè)計模式的類型...
摘要:什么是單例模式單例模式是一種十分常用但卻相對而言比較簡單的單例模式。對象就是單例模式的體現(xiàn)??偨Y(jié)單例模式雖然簡單,但是在項目中的應(yīng)用場景卻是相當多的,單例模式的核心是確保只有一個實例,并提供全局訪問。 1. 什么是單例模式? 單例模式是一種十分常用但卻相對而言比較簡單的單例模式。它是指在一個類只能有一個實例,即使多次實例化該類,也只返回第一次實例化后的實例對象。單例模式不僅能減少不必要...
閱讀 2681·2023-04-25 17:33
閱讀 717·2021-11-23 09:51
閱讀 3037·2021-07-30 15:32
閱讀 1497·2019-08-29 18:40
閱讀 2026·2019-08-28 18:19
閱讀 1527·2019-08-26 13:48
閱讀 2313·2019-08-23 16:48
閱讀 2354·2019-08-23 15:56