JS设计模式——单例模式

保证一个类只有一个实例,并提供一个全局的访问点。

一、定义

保证一个类只有一个实例,并提供一个全局的访问点。

有些对象我们只需要一个,比如线程池、全局缓存、window对象以及按需创建的某些对象。实现单例模式的关键是用一个变量来标识单例是否被创建,已创建则直接返回该实例。在传统的OOP编程中可以通过新增一个获取单例的方法来实现,更好的方法是通过代理类实现。

二、代理类实现单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*通过代理类实现单例模式*/

function A(val) {
//do something
console.log(val); //只会执行一次
}

var ProxyA = (function() {
var instanse; //单例
return function(val) {
if (!instanse) {
instanse = new A(val);
}
return instanse;
};
}());
var singal1 = new ProxyA("singal");
var singal2 = new ProxyA("singal2");
console.log(singal1 === singal2); //true

JavaScript是一门无类的语言,实现单例模式只需要保证:只有一个实例,并提供全局访问。JavaScript中的惰性单例更具实用价值,所以创建一个通用的单例模式比较重要。其实现的核心也是闭包和高阶函数。

三、惰性单例

惰性单例是指:只在需要时创建的单例,其实现的核心是一个通用的惰性单例工厂函数。

实现

html部分:

1
<button id="btn_singal">单例模式</button>

JS部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var getSingal=function(fn){  //惰性单例工厂
var instanse;
return function(){
return instanse||(instanse=fn.apply(this,arguments));
};
};

var createSomething=function(){ //实例工厂
var div=document.createElement("div");
div.innerHTML="唯一的DIV";
div.style.display="none";
document.body.appendChild(div);
return div;
};

//把实例工厂函数包装成单例模式,并且提供全局的访问点
var createSomethingSingal=getSingal(createSomething);

document.getElementById("btn_singal").onclick=function(){
var newdiv=createSomethingSingal();
newdiv.style.display="block";
};