javascript设计模式(1)——单例模式
2026-04-28 14:59:28
206
分类:设计模式
1. 单例模式的特点和定义
一个类只有一个实例
对外提供唯一的访问接口
2. 单例模式的实现
2.1 对象字面量
var mySingleton = {
attr1:1,
attr2:2,
method:function (){
console.log("method");
}
}以上创建一个对象,放在全局中,就可以在任何地方访问,要访问对象中的属性和方法,必须通过mySingleton这个对象,也就是说提供了唯一一个访问接口。
缺陷:
这样的方式耦合度极高,例如:要给这个对象添加属性:
mySingleton.width = 1000; //添加一个属性
//添加一个方法会覆盖原有的方法
mySingleton.method = function(){};如果在多人协作中,这样添加属性的方式经常出现被覆盖的危险,可以采用命名空间的方式解决。
//A同学
mySingleton.a = {};
mySingleton.a.method = function(){}都在自己的命名空间中,覆盖的几率会很小。
2.2 使用闭包私有化
扩展mySingleton对象,添加私有的属性和方法,使用闭包的形式在其内部封装变量和函数声明,只暴露公共成员和方法。
var mySingleton = (function (){
//私有变量
var privateVal = '我是私有变量';
//私有函数
function privateFunc(){
console.log('我是私有函数');
}
// 自执行时就返回了一个对象,造成内存浪费
return {
attr1:1,
attr2:2,
method:function (){
console.log("method");
privateFunc();
}
}
})();
mySingleton.method();缺陷:
脚本一加载就被创建,造成资源浪费。
2.3 惰性单例
无论使用对象字面量或者闭包私有化的方式创建单例,都是在脚本一加载就被创建。有时候页面可能不会用到这个单例对象,这样就会造成资源浪费。对于这种情况,最佳处理方式是使用惰性单例,也就是在需要这个单例对象时再初始化。
惰性单例指的是在需要的时候才创建对象的实例。惰性单例是单例模式的重点。
var createLoginLayer=(function(){
var div; // 当自执行时div为undefined
return function(){
if(!div){
div=document.createElement('div');
}
return div; // 当调用函数时返回div对象
}
})();2.4. 使用构造函数
可以使用构造函数的方式,创造单例对象,这是一个透明的单例模式:
function mySingleton(){
//如果缓存了实例,则直接返回
if (mySingleton.instance) {
return mySingleton.instance;
}
//当第一次实例化时,先缓存实例
mySingleton.instance = this;
}
mySingleton.prototype.otherFunc = function (){
console.log("原型上其他方法");
}
var p1 = new mySingleton();
var p2 = new mySingleton();
console.log( p1 === p2 ); //true当第一次使用new调用函数创建实例时,通过函数的静态属性mySingleton.instance把实例缓存起来,在第二次用new调用函数,判断实例已经缓存过了,直接返回,那么第一次得到的实例p1和第二次得到的实例p2是同一个对象。
缺陷:
但是这样做有一个问题,暴露了可以访问缓存实例的属性mySingleton.instance,这个属性的值可以被改变,如果改变后p1不再等于p2。