JS设计模式-单例模式

来源:互联网 发布:oa软件下载 编辑:程序博客网 时间:2024/05/19 17:09
单例模式:
一个类只能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法(静态方法,通常使用getInstance名称),当我们调用这个方法时,如果类持有的引用不为空就返回该引用,否则就创建该类的实例,并且将实例引用赋值给该类保持的那个引用再返回,同时将该类的构造函数定义为私有方法,避免其它函数使用该构造函数来实例化对象,只通过该类的静态方法来得到该类的唯一实例

jQuery就是一个大的单例模式

JS中的对象永远不会完全相等,即使他们拥有相同成员,除非他们是同一个对象
var a = {
aa : '1'
};
var b = {
aa : '1'
};
a == b //false
a === b //false


1、最简单的单例模式
var a = {
attr1 : '',
attr2 : '',
method1 : function(){},
method2 : function(){}
};

这种方式在JS执行的时候,就已经创建了实例对象,但这种方式所有的属性和方法都是公开的,有一定的风险,一般使用这种方式,可以采用下划线来命名私有变量,但并不推荐


2、静态属性中的实例

function Universe(){
//如果存在,直接返回
if(typeof Universe.instance === "object"){
return Universe.instance;
}
this.a = 0;
this.b = 1;
//缓存
Universe.instance = this;
//隐式返回
return this;
}
//测试
var uni = new Universe();
var uni2 = new Universe();
uni === uni2; //true
在构造函数的静态属性中缓存该实例,JS中的函数也是对象,因此也可以有属性,缺点在于该属性是公开的可访问的属性,外部代码可能会修改该属性


3、闭包方法的单例模式
var aa = (function(){
var _a , _b;//私有变量
var that = {};
//公开接口
that.getA = function(){
return _a;
}
that.getB = function(){
return _b;
}
that.setA = function(a){
_a = a;
}
that.setB = function(b){
_b = b;
}
return that;//返回单例
})();
这种方式使用户能知道公开的接口,但不能随意更改私有变量,可是这种方式在执行脚本的时候就产生了一个单例,可能用户根本就不使用这段代码,这样就会造成内存浪费,更好的做法是在需要使用的时候再去实例化


4、需要使用时再去实例化


例子一:
var aa = (function(){
var uniqueInstance;
function Constructor(){
var _a , _b;
var that = {};
that.getA = function(){
return _a;
}
that.getB = function(){
return _b;
}
that.setA = function(a){
_a = a;
}
that.setB = function(b){
_b = b;
}
return that;
}
return {
getInstance : function(){
if(!uniqueInstance){
uniqueInstance = new Constructor();
}
return uniqueInstance;
}
}
})();
//外部调用
aa.getInstance().setA('kong');
console.log(aa.getInstance().getA());
//kong


例子二:
var bb = (function(){
var instance;//单例实例
//单例方法
function Sing(){
this.name = 'kong';
this.age = '18';
}
return {
getInstance : function(){
if(instance === undefined){
instance = new Sing();
}
return instance;
}
}
})();
//测试
var test = bb.getInstance();
console.log(test.name);
//kong
console.log(test.age);
//18


例子三:
var createMask = (function(){
var mask;
function Add(){
this.add = function(){
document.body.appendChild(document.createElement('div'));
//alert("生成一个DIV");
}
}
return {
getInstance : function(){
if(!mask){
mask = new Add();
}
return mask;
}
}
})();
//测试
createMask.getInstance().add();
//alert("生成一个DIV")
0 0