单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式是一种常用的模式,有一些对象我们往往只需要创建一个,比如线程池,全局缓存,浏览器中的window对象等。在JS开发中,单例模式的用途同样非常广泛,比如当我们单击一个登陆按钮的时候,页面会浮现一个登陆窗口,而且这个窗口是唯一的,无论点击多少次登陆按钮,这个窗口只会被创建一次,那么这个窗口就适合用单例模式来创建。
首先我们先实现一个“透明”的单例类,使用CreateDiv单例类,它的作用是负责在页面中创建唯一的DIV节点,代码如下:
varCreatDiv=(function(){
varinstance;
varCreateDiv=function(html){
if(instance){
returninstance
}
this.html=html;
this.init();
returninstance=this;
};
CreateDiv.prototype.innit=function(){
vardiv=document.createElement('div');
div.innerHTML=this.html;
document.body.appendChild(div);
};
returnCreateDiv;
})();
vara=newCreatDiv('Tom');
varb=newCreatDiv('Jack');
alert(a==b);//true
通过上面这个例子,我们可以能看出,单例模式的大体思想就是先判断这个例子是否存在。转换成代码就是下面这个意思:
var obj;
if(!obj){
obj=xxx;
}
现在我们了解了一些单例模式的实现方法,接下来我们再看惰性单例。惰性单例指的是在需要的时候才创建对象实例,惰性单例是单例模式的重点。就那刚才那个登陆窗口来说,其实用户只是单纯浏览网站时候,其实不需要进行登陆。按照我自己之前的开发方式,就是在页面初始化的时候就创建了这么一个窗口,再将它display为none。学习了单例模式后,发现有更好的办法,那就是惰性单例:只有当用户点击登陆时候我才开始创建并显示这个窗口,然后当用户多次点击登陆时候,其实显示的是同一个登陆窗口。
另外,我们把创建实例对象的职责和管理单例的职责分别放在两个方法里,这两个方法可以独立变化而互不影响,当它们连接在一起的时候,就完成了创建唯一实例对象的功能。这样的做法体现了单一职责原则。上代码,哈哈
vargetSingle=function(fn){
varresult;
return function(){
returnresult||(result=fn.apply(this,arguments));
}
};
varcreateLoginLayer=function(){
vardiv=document.createElement('div');
div.innerHTML='我是登录框';
div.style.display='none';
document.body.appendChild(div);
returndiv;
};
varcreatSingleLoginLayer=getSingle(createLoginLayer);
//假设【登陆】按钮的id是loginBtn
document.getElementById('loginBtn').onclick=function(){
varloginLayer=creatSingleLoginLayer();
loginLayer.style.display='none';
};
网友评论