首页 > 代码库 > JS设计模式——单列模式
JS设计模式——单列模式
核心:保证一个类仅有一个实例,并提供一个访问它的全局访问点
js中的单列模式关键字:创建唯一的对象
(一)基本实现:判断是否已有实例,有则直接返回,否则生成实例
var Single = (function(){ var instance return function(){ if(instance)return instance return instance = this }})()var a = new Single()var b = new Single()console.log(a === b)
这里通过闭包,将单列对象存储在变量instance中
(二)场景:实现一个提示文本的弹出,2秒自动消失,期间再次调用错误提示时不能重复弹出
//实现提示文本function tip(msg){ var instance = $(‘<div>‘+msg+‘</div>‘) $(‘body‘).append(instance) setTimeout(function(){ instance.remove() instance = null },2000) return instance}
目前这种实现是有问题的,多次调用时候会有重复div生成,我们可以根据单例模式的基本实现处理下:
//实现单例var tip_1 = (function(){ var instance return function(msg){ if(instance)return instance = $(‘<div>‘+msg+‘</div>‘) $(‘body‘).append(instance) setTimeout(function(){ instance.remove() instance = null },2000) }})()
(三)通用的单例
--------通用的单例实现代码----------- function getSingle(fn){ let instance return function(){ return instance || (instance = fn.apply(this,arguments)) } }
具体应用一:
function createLoginLayer(){ var div = document.createElement(‘div‘) div.innerHTML = ‘I am login layer‘ div.style.display = ‘none‘ document.body.appendChild(div) return div}var singleCreateLoginLayer = getSingle(createLoginLayer)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‘,getSingle(goAjax))
这个优化目前存着问题,click事件只能执行一次ajax,因为第一次ajax的实例存在了就不会再去执行,所以我们这里需要能够控制到实例
function Single(){ this.instance = null}Single.prototype.getInstance = function(fn){ let _this = this return function(){ return _this.instance || (_this.instance = fn.apply(this,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.getInstance(goAjax))
这样,在success之前,因为实例存在,所以不能被执行多次ajax
扩展场景二:
//缓存代理场景function add(num1,num2){ return num1 + num2}var proxyFun = function(fn){ let cache = {} return function(){ let args = [].join.call(arguments,‘,‘) if(args in cache){ return cache[args] } return cache[args] = fn.apply(this,arguments) }}var proxyAdd = proxyFun(add)proxyAdd(1,1)
这里可以看作代理模式,也可以看作单例模式的扩展
JS设计模式——单列模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。