JavaScript设计模式之单例模式

部分摘自《JavaScript设计模式与开发实践》

单例模式

单例保证一个类只有一个实例,实现方法是一般先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。(保证一个类仅有一个实例,并提供一个访问他的全局访问点)

单例的作用和注意事项

模式作用:

  1. 模块间通信;
  2. 系统中某个类的对象只能存在一个;
  3. 保护自己的属性和方法;

注意事项:

  1. 注意this的使用;
  2. 闭包容易造成内存泄漏,不需要的要赶快干掉;
  3. 注意new的成本;

实现


// 不透明的单例
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('zee1');
var b = Singleton.getInstance('zee2');

alert(a === b); // true;

// 透明的单例
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;
})();

以上的实现过程参考于传统面向对象语言。

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');
// 上述代码等价于
var MyApp = {
	event: {},
	dom: {
		style:{}
	}
};


// 2、使用闭包封装私有变量
var user = (function(){
	var _name = 'zee';
		  _age = 29;
		  return {
				getUserInfo: function(){
					return _name + '-' + _age;
				}
		}
})();

惰性单例

惰性单例指的是在需要的时候才创建对象实例。(是单例模式的重点)

	Singleton.getInstance = (function(){
		var instance = null;
		return function(name){
			if(!instance) {
				instance = new Singleton(name);
			}
			return instance;
		}
	})();

webQQ登录案例

	<html>
		<body>
			<button id="loginBtn">登录</button>
		</body>
	<script>
		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';
		}
	</script>
</html>

封装单例逻辑

	var obj;
	if(!obj){
		obj = xxx;
	}
	
	var getSingle = function(fn){
		var result;
		return function(){
			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');
	return div;
};
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('loginBtn').onclick = function(){
	var loginLayer = createSingleLayer();
	loginLayer.style.display = 'block';
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值