概念
单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点,最常见的例子就是一些项目的配置类。
第一次使用类的构造函数时创建一个实例,而后继续调用构造函数的话就只返回这个实例
简单实现
创建一个单例对象类。
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
透明的单例模式
我们现在的目标是实现一个“透明”的单例类,用户从这个类中创建对象的时候,可以像使用其他任何普通类一样。在下面的例子中,我们将使用 CreateDiv 单例类,它的作用是负责在页面中创建唯一的 div 节点,代码如下:
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( 'sven1' );
var b = new CreateDiv( 'sven2' );
alert ( a === b ); // true
代理实现单例模式
现在我们 把负责管理单例的逻辑移到了代理类 proxySingletonCreateDiv 中。这样一来,CreateDiv 就变成了 一个普通的类,它跟 proxySingletonCreateDiv 组合起来可以达到单例模式的效果。
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 );
惰性单例
惰性单例指的是在需要的时候才创建对象实例.例如网页qq中的登录弹框
由于js是一门无类语音,所以创建实例并不需要那么麻烦,但依然需要注意全局对象容易被污染这一情况
-
- 使用命名空间
-
- 使用闭包封装私有变量
通用惰性单例
所谓通用的惰性单例,实际上就是将管理单例对象和创建单例对象的逻辑分离开来
以创建网页qq登录弹框为例
创建对象逻辑
var getSingle = function( fn ){
var result;
return function(){
return result || ( result = fn .apply(this, arguments ) );
}
};
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';
};
最后
本文介绍了JS设计模式中的代理模式的三种情况,如果你觉得本文对你有用的话,不妨点个赞再走呀...