单例模式的定义:只提供唯一的一个实例来让你访问
js中单例是天然存在的:
var a1={
hello:'js'
}
var a2={
hello:'js'
}
console.log(a1===a2) //false
任意生成的一个对象字面量其实就是一个对象而且他也是唯一的,对象字面量声明对象的方式,每次都会在对内存中创建一个新的空间,所以不管你对象里面的东西一不一样,他们就是不一样的(本质是地址不一样)
但是这样的单例是不可靠的,很容易被覆盖。。。你将a1,a2赋一个新的值,之前的单例对象就被垃圾回收了
如何生成可靠的单例? 用js的闭包可以很容易的做到这一点
var Singleton=function(name){
this.name=name;
}
Singleton.prototype.getName=function(){
return this.name;
}
Singleton.getInstance=(function(){
var instance=null;
return function(name){
if(!instance) return instance=new Singleton(name);
return instance;
}
})()
var one=Singleton.getInstance('I am first one');
var two=Singleton.getInstance('I am second one');
console.log(one===two); //true
console.log(one);
console.log(two);
这样就完成了一个简单的单例模式,书上将这种写法称为 ‘不透明’ 的单例模式,因为生成一个单例要通过 Singleton.getInstance 这个方法来获得,不能像正常创建对象那样,也就是new Singleton() 这样,这种称为 ‘透明’ 的单例模式;
然而,其实单例模式的实现方式上:就是维护一个可访问的变量,来标志是否已经生成了一个实例了,如果生成了就将他返回,没有生成就创建一个,保存起来
那么,闭包的优势又体现出来了:
var Singleton=(function(){
var instance=null;
function SingletonHelper(name){
if(instance) return instance;
this.name=name;
return instance=this; //将第一个new 产生的对象保存在instance 下一个new 要去生成的时候就会返回这个实例
}
SingletonHelper.prototype.getName=function(){
return this.name;
}
return SingletonHelper;
})()
var one=new Singleton('I am first one');
var two= new Singleton('I am second one');
console.log(one);
console.log(two);
console.log(one===two);
这样就可以正常的去new 一些对象,而且不管你new 几个,结果都是一样的,都是第一个生成的那个对象