JavaScript單例模式能不能去實(shí)例只留單原理解析
一、單例模式的分類
一個(gè)環(huán)境中有且只有一個(gè)實(shí)例,并且當(dāng)前環(huán)境可以訪問到它。往小了說,當(dāng)前環(huán)境可以是一個(gè)函數(shù)作用域、塊級(jí)作用域,往大了說可以是全局window或者global環(huán)境。如果按照實(shí)例的創(chuàng)建時(shí)機(jī)進(jìn)行單例模式的分類,有:
- 普通單例模式:在環(huán)境初始時(shí)就創(chuàng)建
- 惰性單例模式:在某個(gè)特定的時(shí)機(jī)才創(chuàng)建
二、惰性單例模式
從單例模式的定義出發(fā),一個(gè)環(huán)境中有且只有一個(gè)實(shí)例,并且使用時(shí)才去創(chuàng)建它,那么就可以把當(dāng)前單例模式稱之為惰性單例模式
- 惰性,指的是只有在使用的時(shí)候才去創(chuàng)建
- 單例,指的是當(dāng)前環(huán)境有且只有單一的一個(gè)實(shí)例
彈窗案例
:在頁(yè)面打開的時(shí)候,頁(yè)面中有登錄按鈕,在點(diǎn)擊時(shí),需要?jiǎng)?chuàng)建一個(gè)dom節(jié)點(diǎn)。
(1)首先,實(shí)現(xiàn)一個(gè)功能函數(shù):創(chuàng)建節(jié)點(diǎn)的函數(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變量在當(dāng)前環(huán)境不銷毀,如果該變量已經(jīng)存在,直接返回,如果沒有,讓當(dāng)前環(huán)境調(diào)用fn功能函數(shù),并賦值給result。該過程保證了當(dāng)前環(huán)境只有一個(gè)實(shí)例。
(3)將創(chuàng)建節(jié)點(diǎn)的函數(shù)和管理單例的函數(shù)糅合
var createSingleDom = createSingle(domFun)
(4)最后,在點(diǎn)擊按鈕的時(shí)候,進(jìn)行實(shí)例的創(chuàng)建
var loginBtn = document.querySelector('.login') loginBtn.onclick = function () { var loginDom = createSingleDom() console.log(loginDom) loginDom.style.display = 'block' }
該過程實(shí)現(xiàn)了只有在點(diǎn)擊登錄按鈕的時(shí)候才創(chuàng)建節(jié)點(diǎn),是惰性的。
整個(gè)過程,將創(chuàng)建惰性實(shí)例的過程進(jìn)行了分解,更易于修改和維護(hù),如果,創(chuàng)建的不是div節(jié)點(diǎn),而是,image圖片、iframe嵌套網(wǎng)頁(yè)、倒計(jì)時(shí)等其他內(nèi)容,只需要替換步驟(1)中的內(nèi)容即可。
這里的例子,我們嚴(yán)格的強(qiáng)調(diào)一個(gè)實(shí)例的事兒。
二、普通單例模式
在vue中的應(yīng)用:我們知道vue
是一個(gè)漸進(jìn)式框架,主要實(shí)現(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)
的方式進(jìn)行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ù)列表中的第一個(gè) 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í)候,會(huì)將該插件推入到數(shù)組installedPlugins
中去,再次執(zhí)行vue.use(xxx)
的時(shí)候,installedPlugins.indexOf(plugin) > -1
為true
,則終止后續(xù)邏輯的執(zhí)行。也就說,vue.use(xxx)
只會(huì)讓該插件執(zhí)行一次install
的安裝。
再看 const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
,是不是發(fā)現(xiàn),這里也是單例模式的影子,當(dāng)this._installedPlugins
不存在時(shí)為其賦值為[]
,當(dāng)前存在時(shí)直接返回。
單例模式,去掉具體的例,就剩單模式。就像當(dāng)前例子中,install只執(zhí)行一次,this._installedPlugins只初始化一次一樣,就體現(xiàn)了一個(gè)單字。那這算不算單(例)模式呢?
總結(jié)
單例模式是不是可以去實(shí)例,只留單呢?這樣,很多只執(zhí)行一次的邏輯也就和單例模式能搭上關(guān)系了。仁者見仁智者見智,能不能去,純屬個(gè)人想法。因?yàn)?,?yōu)秀的單例模式,是經(jīng)過無數(shù)的程序案例得出的經(jīng)驗(yàn)性匯總。
以上就是JavaScript單例模式能不能去實(shí)例只留單原理解析的詳細(xì)內(nèi)容,更多關(guān)于JavaScript單例模式去實(shí)例的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信公眾號(hào) 提示:Unauthorized API function 問題解決方法
這篇文章主要介紹了微信公眾號(hào) 提示:Unauthorized API function 問題解決方法的相關(guān)資料,這里提供了出現(xiàn)提示的解決方法,需要的朋友可以參考下2016-12-12微信小程序 flex實(shí)現(xiàn)導(dǎo)航實(shí)例詳解
這篇文章主要介紹了微信小程序 flex實(shí)現(xiàn)導(dǎo)航實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04微信小程序 五星評(píng)價(jià)功能的實(shí)現(xiàn)
這篇文章主要介紹了微信小程序 五星評(píng)價(jià)功能的實(shí)現(xiàn)的相關(guān)資料,這里附有實(shí)例代碼及實(shí)現(xiàn)效果圖,需要的朋友可以參考下2017-03-03JavaScript數(shù)組 幾個(gè)常用方法總結(jié)
這篇文章主要介紹了JavaScript數(shù)組 幾個(gè)常用方法,主要概述的方法有filter()、map()、sort()、reduce()、forEach(),這些方法都是JavaScript常用到的方法,下面文章內(nèi)容詳細(xì)介紹了他們的語法、參數(shù)、返回值等資料,需要的朋友可以參考一下2021-11-11微信小程序-getUserInfo回調(diào)的實(shí)例詳解
這篇文章主要介紹了微信小程序-getUserInfo回調(diào)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10微信小程序 Button 組件詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了微信小程序 Button 組件詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-01-01微信小程序 animation API詳解及實(shí)例代碼
這篇文章主要介紹了 微信小程序 animation API詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10