摘要:什么時候需要用到單例模式呢其實單例模式在日常開發(fā)中的使用非常的廣泛,例如各種浮窗像登錄浮窗等,無論我們點擊多少次,都是同一個浮窗,浮窗從始至終只創(chuàng)建了一次。這種場景就十分適合運用單例模式。
單例模式 什么是單例模式?
單例模式的定義:一個類僅有一個實例,并且可以在全局訪問。
什么時候需要用到單例模式呢?其實單例模式在日常開發(fā)中的使用非常的廣泛,例如各種浮窗、像登錄浮窗等,無論我們點擊多少次,都是同一個浮窗,浮窗從始至終只創(chuàng)建了一次。這種場景就十分適合運用單例模式。
我們創(chuàng)建一個“最老的人”的類,很明顯,“最老的人”有且只有一個。這很符合我們單例模式的運用場景。我們先來看看完整代碼:
var oldestMan = function (name) { this.name = name; } oldestMan.prototype.getName = function () { console.log(this.name); } //引入一個代理函數(shù)和閉包的概念 var createOldestMan = (function () { var instance; return function (name) { if (!instance) { instance = new oldestMan(name); } return instance; } })(); var personA = createOldestMan("holz"); var personB = createOldestMan("Amy"); personA.getName(); // holz personB.getName(); // holz
我們可以在控制臺上看到即使調用了兩次createOldestMan并且賦了不一樣的值,但兩次getName()輸出的都是第一次的“holz”。這就是單例模式。
代碼看不太懂?沒關系,現(xiàn)在給大家一一講解。
首先我們創(chuàng)建了一個oldestMan類,創(chuàng)建了一個name屬性。然后我們通過 prototype 給它添加一個getName()方法用來獲取oldestMan的名字,相信到這里大家都是懂的,然后下面一段代碼就是重點了,也比較難理解。我們打這段代碼多帶帶拿出來將一下。
//引入一個代理函數(shù)和閉包的概念 var createOldestMan = (function () { var instance; return function (name) { if (!instance) { instance = new oldestMan(name); } return instance; } })();
首先,我們不用管什么是代理函數(shù),之所以叫它代理函數(shù)是因為它輔助我們實現(xiàn)單例模式的效果,這段函數(shù)第一個關鍵點是 createOldestMan() 是一個立即執(zhí)行函數(shù)。立即函數(shù)在聲明的時候就會立即執(zhí)行,也就是在聲明createOldestMan的時候這個函數(shù)就會執(zhí)行,它會聲明一個instance 變量,然后返回一個函數(shù)給createOldestMan。createOldestMan就相當于:
var createOldestMan = function (name) { if (!instance) { instance = new oldestMan(name); } return instance; }
第二個關鍵點是:這里利用了 閉包 的概念。
閉包是什么呢?我只需要記住當函數(shù)在定義時的語法作用域之外被調用,卻還能訪問定義時的語法作用域時,就是產生了閉包。
我們來看一下我們的代碼,函數(shù)先定義了一個instance,然后再返回一個function(name),這個function(name)里面用到了instance變量。在正常情況下,在立即執(zhí)行函數(shù)執(zhí)行之后,instance變量就會被JavaScript的垃圾回收機制回收,但是因為function(name)被返回到了外部,而function(name)隨時會被調用,隨時會訪問到instance變量,所以instance變量被保留在了內存中。這就產生了閉包。也就是說,function(name)被賦值給了外部的createOldestMan,在外部的語法作用域中執(zhí)行,但還可以訪問到定義時內部的語法作用域中的instance。
所以在 立即執(zhí)行函數(shù) 和 閉包 的作用下,instance只被申請了一次,也就是只有一個instance。也就是說,我們無論執(zhí)行多少次createOldestMan("..."),instance只會是第一次的那個值。所以我們就可以判斷instance是否已經被實例化了,來給instance賦值,如果instance已經被實例化,就返回instance。這就達到了一個類只有一個實例的效果。
通用的單例模式我還可以改造一下代碼,因為在開發(fā)中,我們可能不僅只有一個單例,所以我們應該讓代碼能夠變得各個單例通用。我們應該在哪里改呢?沒錯,改代理函數(shù)。我們只需要把代理函數(shù)中的oldestMan()提取出來,改為以參數(shù)的形式傳值,不局限于oldestMan()。
var singleObj; var createSingleton = function (fn) { return function (text) { if (!singleObj) { singleObj = new fn (text); } return singleObj; } }
這樣我們就可以把單例作為參數(shù)傳進去,用它實現(xiàn)不同的單例了。
完整代碼是這樣的:
var oldestMan = function (name) { this.name = name; } oldestMan.prototype.getName = function () { console.log(this.name); } //一個通用的代理函數(shù) var singleObj; var createSingleton = function (fn) { return function (text) { if (!singleObj) { singleObj = new fn (text); } return singleObj; } } var person_1 = createSingleton(oldestMan)("holz"); var person_2 = createSingleton(oldestMan)("tom"); person_1.getName(); //holz person_2.getName(); //holz
同樣,即使再次調用createSingleton并傳入不同的值,輸出的依舊是第一次的“holz”。
總結單例模式的定義:一個類僅有一個實例,并且可以在全局訪問。
適用場景:其實單例模式在日常開發(fā)中的使用非常的廣泛,例如各種浮窗、像登錄浮窗等,無論我們點擊多少次,都是同一個浮窗,浮窗從始至終只創(chuàng)建了一次。這種場景就十分適合運用單例模式。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90370.html
摘要:使用構造函數(shù)如果被實例化過,就返回實例化的結果這種方式比較簡潔,通過判斷是否已經實例化過,但是也沒啥安全性,如果在外部修改那很可能單例模式就被破壞了。 摘要 單體模式也有人稱為單例模式,是javaScript 中最基本但又最有用的模式之一。 什么是單體 一講到概念第一反應就是WTFshowImg(https://segmentfault.com/img/bVSUdx?w=600&h=3...
摘要:本系列為設計模式與開發(fā)實踐作者曾探學習總結,如想深入了解,請支持作者原版單例模式實現(xiàn)單例模式單例模式的定義是保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。 本系列為《JavaScript設計模式與開發(fā)實踐》(作者:曾探)學習總結,如想深入了解,請支持作者原版 單例模式 實現(xiàn)單例模式 單例模式的定義是:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。單例模式是一種常用的模式...
摘要:訂閱模式的一個典型的應用就是后面會寫一篇相關的讀書筆記。享元模式享元模式的核心思想是對象復用,減少對象數(shù)量,減少內存開銷。適配器模式對目標函數(shù)進行數(shù)據(jù)參數(shù)轉化,使其符合目標函數(shù)所需要的格式。 設計模式 單例模式 JS的單例模式有別于傳統(tǒng)面向對象語言的單例模式,js作為一門無類的語言。使用全局變量的模式來實現(xiàn)單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個實例...
摘要:橋接模式的核心在于將抽象部分和它的實現(xiàn)部分分離,使它們都可以獨立的變化。看起來這個版本已經很完美了不,它仍然有可以優(yōu)化的空間,即題目提到的橋接模式。使用橋接模式的實現(xiàn)版本這個實現(xiàn)包含了三個函數(shù)。這個例子體現(xiàn)了橋接模式的作用。 我寫的程序員面試系列文章 Java面試系列-webapp文件夾和WebContent文件夾的區(qū)別? 程序員面試系列:Spring MVC能響應HTTP請求的原因?...
本回內容介紹 上一回聊到JS中模擬接口,裝飾者模式,摻元類,分析了backbone的繼承源碼,感覺還好吧! 介一回,偶們來聊一下在JS單例模式(singleton),單例模式其實運用很廣泛,比如:jquery,AngularJS,underscore吖蝦米的都是單例模式,來吧,直接開始咯: 1. 單例模式 保證一個類只有一個實例,從全局命名空間里提供一個唯一的訪問點來訪問該對象。其實之前寫過的對象...
閱讀 2929·2021-10-14 09:43
閱讀 2867·2021-10-14 09:42
閱讀 4640·2021-09-22 15:56
閱讀 2356·2019-08-30 10:49
閱讀 1587·2019-08-26 13:34
閱讀 2370·2019-08-26 10:35
閱讀 591·2019-08-23 17:57
閱讀 2023·2019-08-23 17:15