基本概念
保证一个类仅有一个实例,并且提供一个访问它的全局访问点。
单例的实现
传统语言描述的单例模式JavaScript实现
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('seven1');
var b = SingleTon.getInstance('seven2');
JavaScript的单例模式实现
实现原理:利用闭包来保持对一个局部变量的引用,这个变量保存着首次创建的唯一的实例
SingleTon.getSingle = (function(){
var instance = null;
return function(name){
if(!instance){
instance = new SingleTon(name);
}
return instance;
}
})();
单例的运用
惰性单例模式
只在需要的时候才创建该单例
var SingleTon = function(foo){
var instance = null;
return function(){
return instance || (instance = foo.apply(this,arguments));
}
};
var createLoginLayer=(function(){
var div;
return function(){
if(!div){
div=document.createElement('div'); //创建一个登录框
}
return div;
}
})();
document.getElementById('loginBtn').onclick=function(){
var loginLayer=createLoginLayer();
loginLayer.style.display='block';
};
当用户第一次点击登录按钮时,来创建并显示登录窗口,之后重复点击按钮不会重复创建
缓存函数的计算结果
以下是不缓存的写法,非常慢!
function foo(n){
results = n < 2 ? n : foo(n - 1) + foo(n - 2);
return results;
}
console.log(foo(40)); //得计算好几秒
以下是缓存写法,基本瞬间出结果!
var foo = (function(){
var cache = {};
return function(n){
if(!cache[n]){
cache[n] = n < 2 ? n : foo(n - 1) + foo(n - 2);
}
return cache[n];
};
})();
console.log(foo(100));
命名空间
单例模式可以提供一个命名空间,例如jQuery库的命名空间为jQuery或$。命名空间的使用是为了让代码更加整洁,在多人协作开发的情况下,不同的人定义的变量很有可能重复,此时就需要使用命名空间来约束每个人定义的变量,使相同名称的变量放在不同的命名空间中,避免相互干扰
// A程序员的命名空间
var A = {
get: function(id){
return document.getElementById(id);
}
css: function(id,key,value){
get(id).style[key] = value;
}
}
// B程序员的命名空间
var B = {
get: function(className){
return document.getElementByClassName(className)[0];
}
css: function(className,key,value){
get(className).style[key] = value;
}
}
A、B两个命名空间中都有一个get方法和一个css方法,用于元素获取和元素样式修改,不同的是A是通过id来获取元素,而B是通过class来获取元素,通过命名空间,可以使这些相同名称的方法共存,使用时指定相应的命名空间即可。
单例的优点与缺点
优点
单例模式声明一个命名空间,它生成一个唯一的全局变量
在实现同一个功能的地方比通过new新创建对象对内存对资源的占用更据优势
缺点
它的扩展性不好,对一个单例对象里面的方法重写时会破坏原有的需求
灵活性不好, 当某个需要实现该功能的需求需要变动时,而其他的又不需要变动时,单例对象就不好处理了

