单例模式定义:保证一个类仅有有一个实例,并提供一个访问它的全局访问点。
应用场景:有一些对象只需要一个。如线程池、全局缓存、浏览器中的window对象等。
实现一:
var Singleton = function(name) {
this.name = name;
this.instance = null;
}
Singleton.prototype.getName = function() {
alert(this.name);
};
Singleton.getInstance = function() {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
};
var a = Singleton.getInstance('sven');
实现一的缺点:增加了这个“类”的不透明性,使用者必须知道这是一个单例类,跟以往通过new的方式获取对象不同。
实现二:
var CreateDiv = (function(){
var instance;
var CreateDiv = function(html) {
if(instance)
return instance;
this.html = html;
this.init();
return instance = this;
};
CreateDiv.prototype.init = function(){
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
return CreateDiv;
})();
var a = new CreateDiv('sven');
实现二的缺点:使用了自执行的匿名函数和闭包,并让匿名函数返回了真正的Singleton构造方法,增加了程序复杂度。
实现三:用代理实现单例模式
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 a = new ProxySingletonCreateDiv('sven');
实现三将负责管理单例的逻辑移到了代理类中。这样一来,将CreateDiv和ProxySingletonCreateDiv组合起来就可实现单例模式。
实现四:惰性单例(需要时才创建对象实例) 重点
var createLoginLayer = (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 = createLoginLayer();
loginLayer.style.display = 'block';
};