單例模式的定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
傳統面向類的單例模式實現
var Singleton = function (name) {
this.name = name;
this.instance = null;
}
Singleton.prototype.getName = function () {
alert(this.name)
}
Singleton.getInstance = function (name) {
if (!this.instance) {
this.instance = new Singleton(name)
}
return this.instance
}
var a = Singleton.getInstance('sven1');
var b = Singleton.getInstance('sven2');
alert( a===b ) //true
這種方式創建單例類和以往不同的是,以往使用new(…)來獲取對象,而這裏使用Singleton.getInstance(…)來獲取對象。使用者要知道這是一個單例類。
JavaScript中的單例模式
在JavaScript中,會把全局變量當做單例模式來使用。比如:
var a = {}
通過這種方式創建的變量a是獨一無二的,但是在JavaScript中全局變量會帶來很多問題,尤其是要注意全局變量的污染。我們可以採用以下辦法:
1 使用命名空間
var namespace1 = {
a: function(){.....},
b: function(){.....}
}
2 使用閉包封裝私有變量
var user = (function () {
var _name = 'sven',
_age = 29;
return {
getUserInfo: function () {
return _name + '-' + _age
}
}
})();
惰性單例
有這樣的需求:點擊一個按鈕後,彈出一個登陸框。很明顯這個登錄框在整個頁面中是唯一的,在創建的時候我們要注意,只有當點擊後才創建這個登錄框,而且一旦創建,就不必要重複創建!
var createDiv = (function () {
var div;
return function () {
if (!div) {
div = document.createElement('div');
div.innerHTML = '我是登錄的浮窗';
div.style.display = 'none';
document.body.appendChild(div)
}
return div
}
})();
document.getElementById('loginBtn').onclick = function () {
var loginLayer = createDiv();
loginLayer.style.display = 'block';
}
這段代碼中,我們使用了一個立即執行函數,立即執行函數的作用就是創建一個獨立的函數作用域,避免變量的污染。立即函數執行後,返回了一個函數,在該函數中判斷變量div是否爲undefied,如果是的話,再創建。因此在點擊事件的回調函數中,我們調用這個方法,只會創建唯一一個div。