Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a5b8f76

Browse files
committed
singleton complete
1 parent 977cab0 commit a5b8f76

File tree

1 file changed

+109
-10
lines changed

1 file changed

+109
-10
lines changed

singleton/singleton.js

Lines changed: 109 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,29 @@ var b = Singleton.getInstance('seven2');
2020
alert(a === b); // true
2121

2222
//或者
23-
var Singleton = function(name){
23+
var Singleton1 = function(name){
2424
this.name = name;
2525
}
2626

27-
Singleton.prototype.getName = function(){
27+
Singleton1.prototype.getName = function(){
2828
alert(this.name);
2929
}
3030

31-
Singleton.getInstance = (function(){
31+
Singleton1.getInstance = (function(){
3232
var instance = null;
3333
return function(name){
3434
if(!instance){
35-
instance = new Singleton('name');
35+
instance = new Singleton1('name');
3636
}
3737
return instance;
3838
}
3939
})();
4040

41-
var a = Singleton.getInstance('seven1');
42-
var b = Singleton.getInstance('seven2');
41+
var a = Singleton1.getInstance('seven1');
42+
var b = Singleton1.getInstance('seven2');
4343
alert(a === b); // true
4444

45-
//2.透明的单例模式。上述简单的单例模式并不透明,必须要知道Singleton对象有getInstance方法可以创造单例,并不能直接new
45+
//2.透明的单例模式。上述简单的单例模式并不透明,必须要知道Singleton对象有getInstance方法可以创造单例,并不能直接new
4646
//下面代码负责在页面中创建唯一的div节点
4747
var CreatDiv = (function(){
4848
var instance;
@@ -71,12 +71,12 @@ alert(a === b); //true
7171
//虽然上述例子实现了单例透明,但是singleton构造函数没有做到职责单一,一个方法干了两件事情,第一,是创建对象和
7272
//执行初始化init方法,第二是保证只有一个对象
7373
//用代理模式实现单例模式可解决此问题
74-
var CreatDiv = function(html){
74+
var CreatDiv1 = function(html){
7575
this.html = html;
7676
this.init();
7777
};
7878

79-
CreatDiv.prototype.init = function(){
79+
CreatDiv1.prototype.init = function(){
8080
var div = document.createElement('div');
8181
div.innerHTML = this.html;
8282
document.body.appendChild(div);
@@ -87,7 +87,7 @@ var ProxySingetonCreateDiv = (function(){
8787
var instance;
8888
return function(){
8989
if(!instance){
90-
instance = new CreatDiv(html);
90+
instance = new CreatDiv1(html);
9191
}
9292
return instance;
9393
}
@@ -97,3 +97,102 @@ var a = new ProxySingetonCreateDiv('seven1');
9797
var b = new ProxySingetonCreateDiv('seven2');
9898

9999
alert(a === b);
100+
101+
/*前面的单例更多地接近于传统面向对象语言,是以类为中心的,比如java中,如果需要某个对象,就必须先定义一个类,对象就是从类中创建而来的,
102+
而javascript是“无类”语言,因此生搬单例模式并无意义*/
103+
/*单例模式的核心是确保只有一个实例,并提供全局访问。
104+
* 在javascript开发中,我们经常会把全局变量当做单例来使用,但全局变量很容易造成命名空间污染和变量冲突,所以可以用以下几种方式降低污染*/
105+
106+
//1.使用命名空间(适当地将属性和方法放入命名空间,并不会杜绝全局变量,但可以减少全局变量的数量),如:
107+
var namespace1 = {
108+
a:function(){
109+
alert(1);
110+
},
111+
b:function(){
112+
alert(2);
113+
}
114+
}
115+
//或者动态地创建命名空间
116+
var myapp = {};
117+
myapp.namespace = function(name){
118+
var parts = name.split('.');
119+
var current = myapp;
120+
for(var i in parts){
121+
if(!current[parts[i]]){
122+
current[parts[i]] = {};
123+
}
124+
current = current[parts[i]];
125+
}
126+
};
127+
128+
myapp.namespace('event');
129+
myapp.namespace('dom.style');
130+
//上述代码等价于:
131+
var myapp = {
132+
event:{},
133+
dom:{
134+
style:{}
135+
}
136+
};
137+
138+
//2.使用闭包封装私有变量(这种方法把一些变量封装在闭包的内部,只暴露一些接口跟外界通信)
139+
var user = (function(){
140+
var _name = 'seven',
141+
_age = 27;
142+
return {
143+
getUserInfo:function(){
144+
return _name + '-' + _age;
145+
}
146+
}
147+
})();
148+
149+
/*惰性单例是单例模式的重点。惰性单例指的是在需要的时候才创建对象实例,
150+
而不是在页面加载好的时候就创建,白白浪费DOM节点。*/
151+
//传统面向对象惰性单例模式如上述的Singleton.getInstance,我们再来回忆一次代码
152+
Singleton.getInstance = function(){
153+
var instance = null;
154+
return function(name){
155+
if(!instance){
156+
instance = new Singleton(name);
157+
}
158+
return instance;
159+
}
160+
}
161+
162+
//下面介绍javascript中与全局变量结合实现惰性的单例
163+
var createLoginLayer = (function(){
164+
var div;
165+
return function(){
166+
if(!div){
167+
div = document.createElement('div');
168+
div.innerHTML = '我是登录框';
169+
div.style.display = 'none';
170+
document.body.appendChild(div);
171+
}
172+
return div;
173+
}
174+
})();
175+
176+
//上面完成了一个可用的单例模式,但是违法了单一职责原则,创建对象和管理单例的逻辑都放在了createLoginLayer对象内部。
177+
//把如何管理单例的逻辑从原来的代码中抽离出来,封装在getSingle内
178+
var getSingle = function(fn){
179+
var result;
180+
return function(){
181+
return result || (result = fn.apply(this,arguments));
182+
}
183+
};
184+
185+
var createLoginLayer = function(){
186+
var div = document.createElement('div');
187+
div.innerHTML = '我是登录框';
188+
div.style.display = 'none';
189+
document.body.appendChild(div);
190+
return div;
191+
}
192+
193+
var createSinleLoginLayer = getSingle(createLoginLayer);
194+
195+
document.getElementById("loginBtn").onclick = function(){
196+
var loginLayer = createSinleLoginLayer();
197+
loginLayer.style.display = 'block';
198+
}

0 commit comments

Comments
 (0)