單例模式:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。html
1、實現一個標準的單例模式,用一個變量來標誌當前是否已經爲某個類建立過對象, 若是是,則在下一次獲取該對象實例時,直接返回以前建立的對象閉包
示例:app
1 var Singleton = function(name){ 2 this.name = name; 3 this.instance = null; // 使用一個變量來表示是否已經建立該對象 4 }; 5 6 Singleton.prototype.getName = function(){ 7 console.log(this.name); 8 }; 9 10 Singleton.getInstance = function(name){ 11 if (!this.instance){ 12 this.instance = new Singleton(name); 13 } 14 return this.instance; 15 }; 16 17 var a = Singleton.getInstance("sven1"); 18 var b = Singleton.getInstance("sven2"); 19 20 console.log(a === b); // true 21 console.log(a.getName() + b.getName()); // sven1 sven1
或者另外一種寫法:函數
1 var Singleton= function(name){ 2 this.name = name; 3 }; 4 Singleton.prototype.getName = function(){ 5 console.log(this.name); 6 }; 7 8 Singleton.getInstance = (function(){ 9 var instance = null; // 是否已建立對象的標誌 10 return function(name){ 11 if (!instance){ 12 instance = new Singleton(name); 13 } 14 return instance; 15 }; 16 })(); 17 18 var a = Singleton.getInstance("A"); 19 var b = Singleton.getInstance("B"); 20 21 console.log(a === b); // true 22 console.log(a.getName() + b.getName()); // A A
2、使用代理實現單利模式this
下面的例子中,將使用 CreateDiv 單例類,做用是負責在頁面中建立惟一的 div 節點spa
1 //建立 div 2 var CreateDiv = function(html){ 3 this.html = html; 4 this.init(); 5 }; 6 CreateDiv.prototype.init = function(){ 7 var div = document.createElement("div"); 8 div.innerHTML = this.html; 9 document.body.appendChild(div); 10 }; 11 12 //單例模式控制類 proxySingletonCreateDiv 13 var ProxySingletonCreateDiv = (function(){ 14 var instance = null; 15 return function(html){ 16 if (!instance){ 17 instance = new CreateDiv(html); 18 } 19 return instance; 20 } 21 })(); 22 23 var a = new ProxySingletonCreateDiv("sven1"); 24 var b = new ProxySingletonCreateDiv("sven2"); 25 console.log(a===b);
3、JavaScript 中的單例模式prototype
單利模式的核心是確保只有一個示例,並提供全局訪問代理
全局變量不是單例模式,但咱們能夠把全局變量當成單利模式來時使用;例如:code
var g = {};
全局變量容易形成命名空間污染,應儘可能減小全局變量的使用。減小全局污染的方法:htm
1. 使用命名空間
var namespace1 = { a: function(){ console.log(1); }, b: function(){ console.log(2); } };
2. 使用閉包封裝私有變量
var user = (function(){ var _name = "sven", _age = 29; return { getUserInfo: function(){ return _name + "-" + _age; } } })();
私有變量被封裝在閉包產生的做用域中,外界訪問不到這兩個變量,就能夠避免對全局命令的污染
4、惰性單例
是指在咱們須要的時候才能夠建立對象實例。惰性單例是單例模式的重點。
示例: 這個例子中,咱們把建立實例對象的職責和管理對象的職責分別放置在兩個方法裏,這兩個方法能夠獨立變化而互不影響,當他們連接在一塊兒時,就完成建立惟一實力對象的功能,看起來是一件挺奇妙的事。
1 //管理單例的邏輯代碼 2 var getSingle = function(fn){ 3 var result; 4 return function(){ 5 return result || (result = fn.apply(this, arguments)) 6 } 7 }; 8 9 // 構造函數 10 var createLoginLayer = function(){ 11 var div = document.createElement("div"); 12 div.innnerHTML = "我是登錄懸浮窗"; 13 div.style.display = "none"; 14 document.body.appendChild(div); 15 return div; 16 }; 17 18 var createSingleLoginLayer = getSingle(createLoginLayer); // 建立實例的方法 19 document.getElementById("loginBtn").onclick = function(){ 20 var loginLayer = createSingleLoginLayer(); 21 loginLayer.style.display = "block"; 22 };