**单例模式的定义是:**保证一个类仅有一个实例,并提供一个访问它的全局访问点。
有一些对象我们往往只需要一个,比如线程池、全局缓存、浏览器中的 window 对象等。
单例模式的核心是确保只有一个实例,并提供全局访问。
实现单例模式
要实现一个标准的单例模式并不复杂,无非是用一个变量来标志当前是否已经为某个类创建 过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。
用代理实现单例模式
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);
};
// 接下来引入代理类 proxySingletonCreateDiv:
var ProxySingletonCreateDiv = (function () {
var instance;
return function (html) {
if (!instance) {
instance = new CreateDiv(html);
}
return instance;
}
})();
var a = new ProxySingletonCreateDiv('sven1');
var b = new ProxySingletonCreateDiv('sven2');
alert(a === b);
惰性单例
惰性单例指的是在需要的时候才创建对象实例。
- 我们需要把不变的部分隔离出来,先不考虑创建一个 div 和创建一个 iframe 有多少差异,管 理单例的逻辑其实是完全可以抽象出来的,这个逻辑始终是一样的:用一个变量来标志是否创建 过对象,如果是,则在下次直接返回这个已经创建好的对象:
var obj;
if ( !obj ){
obj = xxx;
}
- 现在我们就把如何管理单例的逻辑从原来的代码中抽离出来,这些逻辑被封装在 getSingle 函数内部,创建对象的方法 fn 被当成参数动态传入 getSingle 函数:
var getSingle = function (fn) {
var result;
return function () {
return result || (result = fn.apply(this, arguments));
}
};
创建单例div,唯一的登录div
var createLoginLayer = function () {
var div = document.createElement('div');
div.innerHTML = '我是登录浮窗';
div.style.display = 'none';
document.body.appendChild(div);
return div;
};
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick = function () {
var loginLayer = createSingleLoginLayer();
loginLayer.style.display = 'block';
};