JavaScript單例模式能不能去實例只留單原理解析
一、單例模式的分類
一個環(huán)境中有且只有一個實例,并且當前環(huán)境可以訪問到它。往小了說,當前環(huán)境可以是一個函數(shù)作用域、塊級作用域,往大了說可以是全局window或者global環(huán)境。如果按照實例的創(chuàng)建時機進行單例模式的分類,有:
- 普通單例模式:在環(huán)境初始時就創(chuàng)建
- 惰性單例模式:在某個特定的時機才創(chuàng)建
二、惰性單例模式
從單例模式的定義出發(fā),一個環(huán)境中有且只有一個實例,并且使用時才去創(chuàng)建它,那么就可以把當前單例模式稱之為惰性單例模式
- 惰性,指的是只有在使用的時候才去創(chuàng)建
- 單例,指的是當前環(huán)境有且只有單一的一個實例
彈窗案例
:在頁面打開的時候,頁面中有登錄按鈕,在點擊時,需要創(chuàng)建一個dom節(jié)點。
(1)首先,實現(xiàn)一個功能函數(shù):創(chuàng)建節(jié)點的函數(shù)
var domFun = function () { var dom = document.createElement('div'); dom.innerHTML = '登錄窗口demo' dom.style.display = 'none'; document.body.appendChild(dom); return dom; }
(2)其次,創(chuàng)建管理單例的函數(shù)
var createSingle = function (fn) { var result; return function () { return result || (result = fn.apply(this, arguments)); } }
采用閉包的形式,讓result變量在當前環(huán)境不銷毀,如果該變量已經存在,直接返回,如果沒有,讓當前環(huán)境調用fn功能函數(shù),并賦值給result。該過程保證了當前環(huán)境只有一個實例。
(3)將創(chuàng)建節(jié)點的函數(shù)和管理單例的函數(shù)糅合
var createSingleDom = createSingle(domFun)
(4)最后,在點擊按鈕的時候,進行實例的創(chuàng)建
var loginBtn = document.querySelector('.login') loginBtn.onclick = function () { var loginDom = createSingleDom() console.log(loginDom) loginDom.style.display = 'block' }
該過程實現(xiàn)了只有在點擊登錄按鈕的時候才創(chuàng)建節(jié)點,是惰性的。
整個過程,將創(chuàng)建惰性實例的過程進行了分解,更易于修改和維護,如果,創(chuàng)建的不是div節(jié)點,而是,image圖片、iframe嵌套網頁、倒計時等其他內容,只需要替換步驟(1)中的內容即可。
這里的例子,我們嚴格的強調一個實例的事兒。
二、普通單例模式
在vue中的應用:我們知道vue
是一個漸進式框架,主要實現(xiàn)視圖的渲染,其他的功能可以可以通過第三方插件按需引入,比如路由插件vue-router
和全局狀態(tài)管理vuex
。
- 路由
vue-router
的使用
import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter);
- 狀態(tài)
vuex
的使用
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex);
vue
通過Vue.use(Vuex)
的方式進行vue-router
和vuex
的安裝,Vue.use
的代碼如下:
Vue.use = function (plugin: Function | Object) { const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) if (installedPlugins.indexOf(plugin) > -1) { return this } // 去掉參數(shù)列表中的第一個 const args = toArray(arguments, 1) // 將Vue作為this推入到參數(shù)的首位 args.unshift(this) if (typeof plugin.install === 'function') { plugin.install.apply(plugin, args) } else if (typeof plugin === 'function') { plugin.apply(null, args) } installedPlugins.push(plugin) return this }
可以看出,首次執(zhí)行vue.use(xxx)
的時候,會將該插件推入到數(shù)組installedPlugins
中去,再次執(zhí)行vue.use(xxx)
的時候,installedPlugins.indexOf(plugin) > -1
為true
,則終止后續(xù)邏輯的執(zhí)行。也就說,vue.use(xxx)
只會讓該插件執(zhí)行一次install
的安裝。
再看 const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
,是不是發(fā)現(xiàn),這里也是單例模式的影子,當this._installedPlugins
不存在時為其賦值為[]
,當前存在時直接返回。
單例模式,去掉具體的例,就剩單模式。就像當前例子中,install只執(zhí)行一次,this._installedPlugins只初始化一次一樣,就體現(xiàn)了一個單字。那這算不算單(例)模式呢?
總結
單例模式是不是可以去實例,只留單呢?這樣,很多只執(zhí)行一次的邏輯也就和單例模式能搭上關系了。仁者見仁智者見智,能不能去,純屬個人想法。因為,優(yōu)秀的單例模式,是經過無數(shù)的程序案例得出的經驗性匯總。
以上就是JavaScript單例模式能不能去實例只留單原理解析的詳細內容,更多關于JavaScript單例模式去實例的資料請關注腳本之家其它相關文章!
相關文章
微信公眾號 提示:Unauthorized API function 問題解決方法
這篇文章主要介紹了微信公眾號 提示:Unauthorized API function 問題解決方法的相關資料,這里提供了出現(xiàn)提示的解決方法,需要的朋友可以參考下2016-12-12