JavaScript设计模式:单例模式

702 阅读2分钟

单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
使用场景:假设当我们点击登陆按钮的时候,页面中会出现一个登陆悬浮框,而这个登陆框是唯一的,无论单击多少次登陆按钮,这个框只会被创建一次。
实现思路:用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象

普通单例模式

var singleton = function(name){
	his.name = name
}
singleton.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('seven1')
var b = singleton.getInstance('seven2')
console.log(a===b) // true

用代理实现单例模式

var proxySingletonCreateDiv = (function(){
	var instance 
	return function(html){
		if(!instance){
			instance = new createDiv(html)
		}
		return instance
	}
})()
var a1 = new proxySingletonCreateDiv('seven1')
var b1 = new proxySingletonCreateDiv('seven2')
console.log(a1===b1) //true

惰性单例模式

var createLoginLayer = (function(){
	var div;
	return function(){
		if(!div){ //全局变量!判断div是否存在,存在即返回div,不存在便创建一个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'
}

通用的惰性单例模式:采用闭包的形式,将参数fn传入

var getSingle = function(fn){
	var result; //使用result保存fn的结果,因为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 = createSingleLoginLayer();
	loginLayer.style.display = 'block'
}

小结:单例模式的核心是确保只有一个实例,并提供全局访问,var 全局变量不是单例模式,但在JavaScript开发中可以把全局变量当成单例使用;闭包(一个函数内部的函数):可以读取函数内部的局部变量的函数,这些变量的值始终保持在内存中,出函数执行后,函数执行的作用域会被销毁,但活动对象不会被销毁。