JS设计模式——单列模式

核心:保证一个类仅有一个实例,并提供一个访问它的全局访问点

js中的单列模式关键字:创建唯一的对象

(一)基本实现:判断是否已有实例,有则直接返回,否则生成实例

var Single = function){
	var instance

	return function){
		ifinstance)return instance
		return instance = this 
	}
}))

var a = new Single)
var b = new Single)
console.loga === b)

这里通过闭包,将单列对象存储在变量instance中

(二)场景:实现一个提示文本的弹出,2秒自动消失,期间再次调用错误提示时不能重复弹出 

//实现提示文本
function tipmsg){
	var instance = $'<div>'+msg+'</div>')
	$'body').appendinstance)

	setTimeoutfunction){
		instance.remove)
		instance = null
	},2000)
	return instance
}

 目前这种实现是有问题的,多次调用时候会有重复div生成,我们可以根据单例模式的基本实现处理下:

//实现单例
var tip_1 = function){
	var instance

	return functionmsg){
		ifinstance)return

		instance = $'<div>'+msg+'</div>')
		$'body').appendinstance)
		setTimeoutfunction){
			instance.remove)
			instance = null
		},2000)
	}
}))

(三)通用的单例

--------通用的单例实现代码-----------
 function getSinglefn){
 	let instance
 	return function){
 		return instance || instance = fn.applythis,arguments))
 	}
 }

  具体应用一:

function createLoginLayer){
	var div = document.createElement'div')
	div.innerHTML = 'I am login layer'
	div.style.display = 'none'
	document.body.appendChilddiv)
	return div
}

var singleCreateLoginLayer = getSinglecreateLoginLayer)
window.onclick = function){			
	var loginLayer = singleCreateLoginLayer)
	loginLayer.style.display = 'block'
}

  通过通用的单例,我们可以将单例的实现和具体业务分离开来,注意:在业务函数中一定要return返回一个具体实例,否则getSingle无效

(四)单例的扩展

  有些特殊的场景,我们需要对通用的单例模式进行扩展:

  扩展场景一:  

//按钮重复提交问题:
$document).on'click',function){
	$.ajax{
		url:'http://www.baidu.com',
		success:function){
			console.log'success')
		}
	})
})
//优化
var goAjax = function){
	return $.ajax{
			url:'http://www.baidu.com',
			success:function){
				console.log'success')
			},
			error:function){
				console.log'error')
			},
		     })
}

$document).on'click',getSinglegoAjax))

  这个优化目前存着问题,click事件只能执行一次ajax,因为第一次ajax的实例存在了就不会再去执行,所以我们这里需要能够控制到实例

function Single){
	this.instance = null
}
Single.prototype.getInstance = functionfn){	
	let _this = this
	return function){		
		return _this.instance || _this.instance = fn.applythis,arguments))
	}
}

var goAjaxSingle = new Single)
var goAjax = function){	
	return $.ajax{
			url:'http://www.baidu.com',
			success:function){
				console.log'success')
				goAjaxSingle.instance = null
			}
		})
}
$document).on'click',goAjaxSingle.getInstancegoAjax))

  这样,在success之前,因为实例存在,所以不能被执行多次ajax

  扩展场景二:

//缓存代理场景
function addnum1,num2){
	return num1 + num2
}

var proxyFun = functionfn){
	let cache = {}
	return function){
		let args = [].join.callarguments,',')
		ifargs in cache){
			return cache[args]
		}
		return cache[args] = fn.applythis,arguments)
	}
}

var proxyAdd = proxyFunadd)
proxyAdd1,1)

  这里可以看作代理模式,也可以看作单例模式的扩展

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注