js設(shè)計(jì)模式中單例模式的簡(jiǎn)要說(shuō)明
一. 認(rèn)識(shí)單例模式
單例模式的意思是,保證一個(gè)類只有一個(gè)實(shí)例,并且有一個(gè)接口供全局訪問(wèn)。它的作用就是防止頻繁創(chuàng)建實(shí)例,浪費(fèi)不必要的內(nèi)存空間和資源消耗,那它有什么實(shí)用場(chǎng)景呢,假如我們?cè)陧?yè)面中有一個(gè)點(diǎn)擊跳出一個(gè)彈窗操作,彈窗應(yīng)該是唯一的,無(wú)論點(diǎn)擊多少次它都應(yīng)該被構(gòu)建一次,那么這個(gè)彈窗就適合用單例模式來(lái)創(chuàng)建。
二. 單例模式的分類
- 簡(jiǎn)單實(shí)現(xiàn)單例模式
- 透明實(shí)現(xiàn)單例模式
- 代理實(shí)現(xiàn)單例模式
- js單例模式
- 惰性單例模式
- 通用惰性單例模式(主要用于 js)
注: 前三種單例模式為用類實(shí)現(xiàn)的思想,通過(guò) new 的方式來(lái)創(chuàng)建實(shí)例,而 javascript 是沒(méi)有類的,可以直接創(chuàng)建實(shí)例,因此并不適用,主要用于后邊三種。
三. 具體實(shí)現(xiàn)和思想學(xué)習(xí)
1. 簡(jiǎn)單實(shí)現(xiàn)單例模式
let Singleton = function ( name ) {
this.name = name;
}
Singleton.instance = null;
Singleton.prototype.getName = function () {
console.log( this.name )
}
Singleton.getInstance = function ( name ) {
if( !this.instance ) {
this.instance = new Singleton( name );
}
return this.instance;
}
let a = Singleton.getInstance('sk');
let b = Singleton.getInstance('ss');
console.log(a);
console.log(a === b) // true實(shí)現(xiàn)思想:將第一次創(chuàng)建的實(shí)例進(jìn)行保存,之后再次創(chuàng)建前判斷是否已經(jīng)創(chuàng)建,如果之前創(chuàng)建過(guò)則返回已經(jīng)保存的實(shí)例,否則創(chuàng)建一個(gè)實(shí)例,將實(shí)例創(chuàng)建和判斷封裝到了一個(gè) getInstance 函數(shù)中,這種方式相對(duì)簡(jiǎn)單,但增加了類的“不透明性”,用一個(gè)函數(shù)來(lái)獲取一個(gè)實(shí)例,而不是以往通過(guò) new 來(lái)創(chuàng)建。
2. 透明單例模式
let CreateDiv = function () {
let instance ;
let CreateDiv = function ( html ) {
if( instance ) {
return instance;
}
this.html = html;
this.init();
return instance = this;
}
CreateDiv.prototype.init = function () {
let element = document.createElement('div');
element.innerHTML = this.html;
document.body.appendChild(element);
}
return CreateDiv;
}();
let a = new CreateDiv('石頭山');
let b = new CreateDiv('哈哈');
console.log(a === b); // true 實(shí)現(xiàn)思想:該方式與前一實(shí)現(xiàn)不同的在于用 new 來(lái)創(chuàng)建實(shí)例,運(yùn)用了閉包來(lái)保存實(shí)例標(biāo)識(shí),從而達(dá)到只能創(chuàng)建唯一實(shí)例,但是如果有一天想創(chuàng)建多個(gè) div 實(shí)例,該代碼就不實(shí)用了,必須修改代碼,因此擴(kuò)展除了代理實(shí)現(xiàn)。
3. 代理實(shí)現(xiàn)單例模式
let CreateDiv = function ( html ) {
this.html = html;
this.init();
}
CreateDiv.prototype.init = function () {
let div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
}
let ProxySingletonCreateDiv = function () {
let instance ;
return function ( html ) {
if( !instance ) {
instance = new CreateDiv( html );
}
return instance;
}
}();
let a = new ProxySingletonCreateDiv('sven1');
let b = new ProxySingletonCreateDiv('sven2');
console.log(a === b); // true實(shí)現(xiàn)思想:CreateDiv 為一個(gè)普通類,將創(chuàng)建和判斷唯一實(shí)例封裝在了代理函數(shù)中,增加了代碼復(fù)用性,彌補(bǔ)了透明單例的不足,需要單例則直接 new ProxySingletonCreateDiv(),需要普通實(shí)例則直接 new CreateDiv(),但是該方式代碼可讀性差,也不采用。
4. js的單例模式
① 使用命名空間來(lái)創(chuàng)建:將所有變量和方法直接放在一個(gè)全局對(duì)象中
let S = {
name: '石頭山',
getName() {
console.log(this.name);
}
}② 使用閉包封裝私有變量:將變量封裝在閉包內(nèi)部,只向全局暴露一個(gè)訪問(wèn)接口
let name = "石頭山";
return {
getName() {
return name;
}
}
}5. 通用惰性單例
// 寫一個(gè)通用的獲取單例的函數(shù) , fn 為執(zhí)行單次的函數(shù)
let getSingle = function ( fn ) {
let result;
return function () {
return result || ( result = fn.apply(this, arguments))
}
}
// 綁定事件
let bindEvent = function () {
document.getElementById('div').addEventListener('click',()=>{
console.log('我出現(xiàn)了')
});
}();
// 無(wú)論渲染多少次,事件只綁定一次
let render = function () {
console.log('開(kāi)始渲染!');
getSingle(bindEvent)
}
render();
render();
render();該方式是 js 中常用的單例實(shí)現(xiàn)方法,再頁(yè)面重復(fù)渲染三次時(shí),監(jiān)聽(tīng)事件只綁定了一次,減少了開(kāi)銷。
惰性體現(xiàn):惰性體現(xiàn)在實(shí)例實(shí)在需要時(shí)創(chuàng)建,并不會(huì)在頁(yè)面加載好就創(chuàng)建。
實(shí)現(xiàn)思想:首先利用閉包和高階函數(shù)封裝了一個(gè)返回單一實(shí)例的函數(shù),其參數(shù)就是一個(gè)只執(zhí)行一次的函數(shù),可以隨時(shí)改變單例的作用,大大增加了代碼的可復(fù)用性。
四. 總結(jié)
單例模式是一種簡(jiǎn)單但非常使用的開(kāi)發(fā)模式,js 開(kāi)發(fā)中,通用惰性單例實(shí)現(xiàn)方式最常用的一中方式,它將創(chuàng)建對(duì)象和管理單例的職責(zé)封裝在兩個(gè)不同的方法中,組合在一起就具有了單例模式的威力。
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
javascript運(yùn)行機(jī)制之this詳細(xì)介紹
這篇文章主要介紹了javascript運(yùn)行機(jī)制之this,需要的朋友可以參考下2014-02-02
JavaScript中Number.MIN_VALUE屬性的使用示例
這篇文章主要介紹了JavaScript中Number.MIN_VALUE屬性的使用示例,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06
JavaScript Break 和 Continue區(qū)別教程
JavaScript Break 和 Continue區(qū)別教程...2007-04-04
JS不用正則驗(yàn)證輸入的字符串是否為空(包含空格)的實(shí)現(xiàn)代碼
下面小編就為大家?guī)?lái)一篇JS不用正則驗(yàn)證輸入的字符串是否為空(包含空格)的實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06
ECMAScript 5嚴(yán)格模式(Strict Mode)介紹
這篇文章主要介紹了ECMAScript 5嚴(yán)格模式(Strict Mode)介紹,本文講解了如何啟用嚴(yán)格模式、啟用嚴(yán)格模式后對(duì)變量和屬性、函數(shù)、with語(yǔ)句的影響,需要的朋友可以參考下2015-03-03
BAT及各大互聯(lián)網(wǎng)公司2014前端筆試面試題--JavaScript篇
很多面試題是我自己面試BAT親身經(jīng)歷碰到的。整理分享出來(lái)希望更多的前端er共同進(jìn)步吧,不僅適用于求職者,對(duì)于鞏固復(fù)習(xí)js更是大有裨益2014-10-10
Typescript中 type 與 interface 的區(qū)別說(shuō)明總結(jié)
這篇文章主要介紹了Typescript中 type 與 interface 的區(qū)別說(shuō)明總結(jié),需要的朋友可以參考下2024-07-07

