JS 單例模式
概要:
單例指一個(gè)類只有一個(gè)實(shí)例,這個(gè)類自行創(chuàng)建這個(gè)實(shí)例。
利用對(duì)象字面量直接生成一個(gè)單例:
var singleton = { prop: 1, method: function(){ console.log(a); //1 }}嚴(yán)格的說對(duì)象字面量可能不算單例模式,生成單例是對(duì)象字面量的作用(已經(jīng)被封裝),而單例模式是一個(gè)設(shè)計(jì)模式(需要自行構(gòu)思或設(shè)計(jì))。
在類內(nèi)部用new生成實(shí)例的單例模式:
var instance;var foo = function(){ if(!instance){ instance = new Singleton(); } return instance; function Singleton(){ this.name = 'single'; this.method = function(){ console.log(this.name); } };} var a = foo();var b = foo();a.method(); //singleconsole.log(a === b); //true單例模式只要檢測(cè)一個(gè)實(shí)例是否被生成。假如沒有實(shí)例,則生成實(shí)例。假如已經(jīng)生成則返回這個(gè)實(shí)例。保證這個(gè)類只有這一個(gè)實(shí)例。
由于hoisting,函數(shù)會(huì)提前聲明,所以 singleton 函數(shù)放在哪都沒所謂,但是每次調(diào)用都會(huì)聲明函數(shù)singleton,可能會(huì)不夠優(yōu)雅。
由于new關(guān)鍵字是執(zhí)行函數(shù),同時(shí)this指向這個(gè)對(duì)象,所以可以判斷類的this是否賦值給instance:
var instance;var Singleton = function(){ if(instance){ return instance; } instance = this; this.name = 'single'; this.method = function(){ console.log(this.name); }} var a = new Singleton();var b = new Singleton();a.method(); //singleconsole.log(a === b); //true這個(gè)例子中,把instance指向了Singleton這個(gè)類,然后在類外部通過new來實(shí)例化,和上例中的new異曲同工。由于是通過修改this來達(dá)到檢測(cè)是否執(zhí)行過Singleton類,所以個(gè)人感覺不夠語義化。
上面的例子用es6重構(gòu)的寫法。
類內(nèi)部new生成單例:
var instance;class foo{ static Singleton(){ if(!instance){ instance = new foo(); } return instance; } method(){ this.name = 'single'; console.log(this.name); }} var a = foo.Singleton();var b = foo.Singleton();a.method(); //singleconsole.log(a === b); //true修改this指向生成單例:
var instance;class foo{ constructor(){ if(!instance){ this.Singleton(); } return instance; } Singleton(){ instance = this; this.name = 'single'; this.method = function(){ console.log(this.name); } }} var a = new foo();var b = new foo();a.method(); //singleconsole.log(a === b); //true 當(dāng)然除了這兩種以外還有別的方式能實(shí)例化一個(gè)單例。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注