定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。通常使用在 線程池、全局緩存等方面。html
var Singleton = function (name) { this.name = name this.instance = null } Singleton.prototype.getName = function () { console.log(this.name) } Singleton.getInstance = function (name) { if(!this.instance){ this.instance = new Singleton(name) } } var a = Singleton.getInstance('張三') var b = Singleton.getInstance('李四') alert(a === b) // true 或者: var Singleton2 = function (name) { this.name = name } Singleton2.prototype.getName = function () { console.log(this.name) } Singleton2.getInstance = (function () { var instance = null; return function (name) { if(!instance){ instance = new Singleton2(name) } return instance } })() var c = Singleton2.getInstance('張三') var d = Singleton2.getInstance('李四') alert(c === d) // true
var Singleton = function (name) { this.name = name this.instance = null } Singleton.prototype.getName = function () { console.log(this.name) } Singleton.getInstance = function (name) { if(!this.instance){ this.instance = new Singleton(name) } } var a = Singleton.getInstance('張三') var b = Singleton.getInstance('李四') alert(a === b) // true 或者: var Singleton2 = function (name) { this.name = name } Singleton2.prototype.getName = function () { console.log(this.name) } Singleton2.getInstance = (function () { var instance = null; return function (name) { if(!instance){ instance = new Singleton2(name) } return instance } })() var c = Singleton2.getInstance('張三') var d = Singleton2.getInstance('李四') alert(c === d) // true
總結:雖然經過 Singleton.getInstance 來獲取 Singleton 類的惟一對象,這種方式相對簡單,但有 一個問題,就是增長了這個類的「不透明性」,Singleton 類的使用者必須知道這是一個單例類, 跟以往經過 new XXX 的方式來獲取對象不一樣,這裏偏要使用 Singleton.getInstance 來獲取對象。緩存
var Singleton = (function () { var instance = null var Singleton = function (name) { if(instance){ return instance } this.name = name this.init() return instance = this; } Singleton.prototype.init = function () { this.getName() } Singleton.prototype.getName = function () { console.log(this.name) } return Singleton })() var a = new Singleton('張三') var b = new Singleton('李四')
var Singleton = (function () { var instance = null var Singleton = function (name) { if(instance){ return instance } this.name = name this.init() return instance = this; } Singleton.prototype.init = function () { this.getName() } Singleton.prototype.getName = function () { console.log(this.name) } return Singleton })() var a = new Singleton('張三') var b = new Singleton('李四')
總結:假設咱們某天須要利用這個類從單例類變成 一個普通的可產生多個實例的類,那咱們必須得改寫 Singleton 構造函數,把控制建立惟一對象 的那一段去掉,這種修改會給咱們帶來沒必要要的煩惱app
var CreateDiv = function( html ){ this.html = html; this.init(); }; CreateDiv.prototype.init = function(){ var div = document.createElement( 'div' ); div.innerHTML = this.html; document.body.appendChild( div ); }; var ProxySingletonCreateDiv = (function(){ var instance; return function( html ){ if ( !instance ){ instance = new CreateDiv( html ); } return instance; } })();
var CreateDiv = function( html ){ this.html = html; this.init(); }; CreateDiv.prototype.init = function(){ var div = document.createElement( 'div' ); div.innerHTML = this.html; document.body.appendChild( div ); }; var ProxySingletonCreateDiv = (function(){ var instance; return function( html ){ if ( !instance ){ instance = new CreateDiv( html ); } return instance; } })();
4. 通用惰性單例模式函數
// 1.咱們能夠經過變量存不存在來決定單例代碼是否執行 // 2.咱們須要把不變的部分隔離出來,管理單例的邏輯從代碼中抽離出來 var Singleton = function (fn) { var instance; return function () { return instance||(instance=fn.apply(this,arguments)) } } var CreateDiv = function (content) { var div = document.createElement('div') div.innerHTML = content document.body.appendChild( div ); } var getSingleCreateDiv = Singleton(CreateDiv) getSingleCreateDiv('1111111')
// 1.咱們能夠經過變量存不存在來決定單例代碼是否執行 // 2.咱們須要把不變的部分隔離出來,管理單例的邏輯從代碼中抽離出來 var Singleton = function (fn) { var instance; return function () { return instance||(instance=fn.apply(this,arguments)) } } var CreateDiv = function (content) { var div = document.createElement('div') div.innerHTML = content document.body.appendChild( div ); } var getSingleCreateDiv = Singleton(CreateDiv) getSingleCreateDiv('1111111')