单例模式的定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
例子1 用代理的方式实现单例模式
下面的代码的功能是在页面中创建一个div
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 ProxyCreateDiv = (function(){
var instance;
return function(html){
if(!instance){
instance = new CreateDiv(html);
}
return instance;
}
})();
var a = new ProxyCreateDiv('div1');
var b = new ProxyCreateDiv('div2');
console.log(a === b); // true
惰性单例
var createLogin = (function(){
var div;
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 = createLogin();
loginLayer.style.display = 'block';
}
上面的代码还存在一些问题,例如违反了单一职责,如果我们下次需要创建的不是div,而是script或者iframe什么的,只能把createLogin重新复制一份出来
下面我们把管理单例的逻辑抽离出来,这些逻辑被单独封装在getSingle函数内部,创建对象的方法fn被当成参数动态传入getSingle函数
var getSingle = function(fn){
var result;
return function(){
return result || (result = fn.apply(this,arguments));
}
};
var createLogin = (function(){
div = document.createElement('div');
div.innerHTML = '登录框';
div.style.display = 'none';
document.body.appendChild(div);
return div;
})();
var createSingleLogin = getSingle(createLogin);
document.getElementById('loginBtn').onclick = function(){
var loginLayer = createSingleLogin();
loginLayer.style.display = 'block';
}
//如果需要创建一个iframe 也是很方便的
var createSingleIframe = getSingle(function(){
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
return iframe;
});
document.getElementById('iframeBtn').onclick = function(){
var iframeLayer = createSingleIframe();
iframeLayer.src = 'http://www.xxx.com';
}
getSingle可以实现很多函数的单例效果
网友评论