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( 'sven1' );
var b = Singleton.getInstance( 'sven2' );
console.log(a.getName()); //sven1
console.log(b.getName()); //sven1
实际上 var b = Singleton.getInstance( 'sven2' );
并没有起作用,没有创建新的对象
通过用代理实现单例模式
需求:我们需要创建一个弹框,页面上多次使用,但是只需要创建一次弹框节点就可以了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
// 模拟单例模式,创建 div a p
// 创建的实现代码:
var createDOM = {
p : function(){
var p = document.createElement('p');
p.innerHTML = '我是p';
document.body.appendChild(p);
return p;
},
div : function(){
var div = document.createElement('div');
div.innerHTML = '我是div';
document.body.appendChild(div);
console.log(create_div);
return div;
},
span : function(){
var obj = document.createElement('span');
obj.innerHTML = '我是span';
document.body.appendChild(obj);
return obj;
}
}
var singleTonCreat = function( fn ){ //代理
var obj;
return function(){
return obj || (obj = fn.apply(this, arguments));
}
};
var creatediv = singleTonCreat( createDOM.span );
creatediv();
</script>
</body>
</html>
javascript 中没有 类 的概念,如果是单纯的为了实现单例模式,而模拟类的样式,就毫无意义; 上面的代码没有模拟类,仅仅是实现了单例模式的功能。
自我思考
学习过程中呢,突然想到,我虽然是要用单例模式,这样很简洁,但是如果我的代码以后被别人修改or使用呢?
里面的 createDOM
我并不应该开放出来给别人使用。如果别人没有注意到单例的方法,只是发现了 createDOM
那我们写的就毫无意义了,他们可以多次增加节点,怎么才能只让别人拿到单例的函数,而其他方法拿不到呢?
解决办法: 还是需要类的概念:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
// 暂时:最终模式!
var createDOM = function createdom(){
var _create = {
p : function(){
var p = document.createElement('p');
p.innerHTML = '我是p';
document.body.appendChild(p);
return p;
},
div : function(){
var div = document.createElement('div');
div.innerHTML = '我是div';
document.body.appendChild(div);
return div;
},
span : function(){
var obj = document.createElement('span');
obj.innerHTML = '我是span';
document.body.appendChild(obj);
return obj;
}
}
var singleTonCreat = function( fn ){
var obj;
return function(){
return obj || (obj = fn.apply(this, arguments));
}
};
this.creatP = singleTonCreat(_create.p);
this.creatDIV = singleTonCreat(_create.div);
this.creatSPAN = singleTonCreat(_create.span);
}
var created = new createDOM();
created.creatP();
created.creatP();
created.creatDIV();
created.creatSPAN();
</script>
</body>
</html>
如上,把代码放到 createDOM
中,只能通过 new 新建对象,而且只能调用我们想让别人使用的三个方法:
this.creatP , this.creatDIV , this.creatSPAN
其他的都拿不到,暂时完美解决需求。