第4章单例模式
4.1 实现单例模式
var Singletion = function(name){
this.name = name;
this.instance = null;
}
Singletion.prototype.getName = function(){
console.log(this.name);
}
Singletion.getIntance = function(name){
if(!this.instance){
this.instance = new Singletion(name);
}
return this.instance;
}
var a = Singletion.getIntance('sven1');
console.log(Singletion.instance); //{ name: 'sven1', instance: null }
var b = Singletion.getIntance('sven2')
console.log(Singletion.instance); //{ name: 'sven1', instance: null }
console.log(a===b); //true
或者
var Singletion = function(name){
this.name = name;
}
Singletion.prototype.getName = function(){
console.log(this.name);
}
Singletion.getIntance = (function(){
var instance = null;
return function(name){
if(!instance){
instance = new Singletion(name);
}
return instance;
}
})()
var a = Singletion.getIntance('sven1');
var b = Singletion.getIntance('sven2')
console.log(ba===b); // true
意义不大
4.2 透明的单例模式
var CreateDiv = (function(){
var instance;
var CreateDiv = function(html){
if(instance){
return instance;
}
this.html = html;
this.init();
return instance = this;
}
CreateDiv.prototype.init = function(){
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
}
return CreateDiv;
})();
var a = new CreateDiv('sven1');
var b = new CreateDiv('sven2');
console.log(a===b); //true
构造函数很奇怪
让这一单例类变成一个普通的可产生多个实例的类,把控制创建去掉,这修改会带来不必要的麻烦
4.3 用代理实现单例模式
var CreateDiv = function(html){
this.html = html;
this.init();
}
CreateDiv.prototype.init = function(){
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
}
var ProxySingletonCreateDiv = (function(){
var instance;
return function(html){
if (!instance) {
instance = new CreateDiv(html)
}
return instance
}
})()
var a = new ProxySingletonCreateDiv('sven1');
var b = new ProxySingletonCreateDiv('sven2');
console.log(a===b);
Create普通类 就可以产生多个实例
缓存代理的应用之一
4.4 Javascript中的单例模式
相对降低全局变量带来的污染
1使用命名空间
对象字面量的方式
var namespace1 = {
a : function(){
alert(1);
},
b:function(){
alert(2);
}
}
动态创建命名空间
var MyApp = {};
MyApp.namespace = function(name){
var parts = name.split('.');
var current = MyApp;
for(var i in parts){
if(!current[parts[i]]){
current[parts[i]] = {};
}
current = current[parts[i]]
}
}
MyApp.namespace('event');
MyApp.namespace('dom.style');
console.dir(MyApp); //{ namespace: [Function], event: {}, dom: { style: {} } }
//等价于
var MyApp = {
event:{},
dom:{
style:{}
}
}
2使用闭包封装私有变量
var user = (function(){
var _name = 'sven', _age = 29;
return {
getUserInfo : function(){
return _name + '-' + _age;
}
}
})()
4.5 惰性单例
WebQQ第一种解决方案是在页面加载完成的时候便创建好这个div窗口会浪费DOM节点
改为用户点击登录按钮的时候才开始创建,失去了单例的效果
so
var createLoginLayer = (function(){
var div;
return function(){
if(!div){
div = document.createElement('div');
div.innerHTML = '我是登录框'
div.style.display = 'none';
document.body.appendChild(div);
}
return div;
}
})()
document.getElementById('loginBtn').onclick = function(){
var loginLayer = createLoginLayer();
loginLayer.style.display = 'block';
}
4.6 通用的惰性单例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button id="loginBtn">点击我执行命令</button>
<button id="loginBtn1">点击我执行命令</button>
<script>
var getSingle = function(fn){
var result;
console.log(result);
return function(){
console.log(result);
return result || (result = fn.apply(this,arguments));
}
}
var createLoginLayer = function(){
var div = document.createElement('div');
div.innerHTML = '我是登录浮窗';
div.style.display = 'none';
document.body.appendChild(div);
console.log(1);
return div;
};
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick = function(){
var loginLayer = createSingleLoginLayer();
loginLayer.style.display = 'block';
}
var createSingleIframe = getSingle(function(){
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
console.log(2);
return iframe;
});
document.getElementById("loginBtn1").onclick = function(){
var loginLayer = createSingleIframe();
loginLayer.src = 'http://www.baidu.com';
}
</script>
</body>
</html>
test.html:13 undefined
test.html:13 undefined
test.html:15 undefined
test.html:25 1
test.html:15 undefined
test.html:40 2
给结点绑定one事件
var bindEvent = function(){
$('div').one('click',function(){
alert('click');
});
};
var render = function(){
console.log('开始渲染列表');
bindEvent();
}
render();
render();
render();
//利用getSingle函数,也能达到一样的效果
var bindEvent = getSingle(function(){
document.getElementById('div').onclick = function(){
alert('click')
}
return true;
})
var render = function(){
console.log('开始渲染列表');
bindEvent();
}
render();
render();
render();