

单例模式【javascript设计模式】
source link: https://webfe.kujiale.com/dan-li-mo-shi-javascriptshe-ji-mo-shi/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

25 December 2017
单例模式【javascript设计模式】
学而时习之,不亦说乎?——孔丘《论语•学而》
单例模式的核心在于: 确保一个实例,并提供全局访问。
首先,单例模式要求只有一个实例,其次这个实例在全局都可以访问到。比如我在实习的时候写的这个页面:
点击邮件获取最新安装包的时候会弹出这个框框,很显然,这个框框只需要被创建一次即可,所以我们可以写下如下的代码:
<button class="J-popup">btn</button>
var popup = (function () {
var div = document.createElement('div');
div.innerHTML = '我是一个框框';
div.style.display = 'none';
document.body.appendChild(div);
return div;
})();
document.getElementsByTagName('J-popup').onclick = function () {
popup.style.display = 'block';
}
这种方式虽然符合单例模式的定义,但是也许我们进入这个页面的时候不会去点这个获取安装包的按钮,那么这个dom节点就被白白浪费了,所以改为惰性创建,修改后的代码如下:
var popup = (function () {
var div;
return function () {
if (!div) {
div = document.createElement('div');
div.innerHTML = '我是一个框框';
div.style.display = 'none';
document.body.appendChild(div);
}
return div;
}
})();
document.getElementsByTagName('J-popup').onclick = function () {
var popupInstance = popup();
popupInstance.style.display = 'block';
}
ok,到这里来说已经是一个比较完美的单例的实践了,但是以上的代码违反了单一职责的原则,这就导致了一个问题:比如要是我需要在创建另一个不同于div的框框,诸如iframe之类的,还需要将popup这个函数重新复制一份然后改一下内部的代码,don't repeat you self !!!
分析一下就会发现原因在于我们把创建对象和管理对象的逻辑都放在了popup函数里了,所以我们要做的仅仅是将它们分离开来:
// 定义一个生成单例对象的函数:
var getSingle = function (fn) {
var instance;
return function () {
return instance || ( instance = fn.apply(this, arguments) );
}
}
现在就可以愉快的创建单例了,比如上面的那个弹框,可以这样子:
var popup = function () {
var div = document.createElement('div');
div.innerHTML = '我是一个框框';
div.style.display = 'none';
document.body.appendChild(div);
return div;
};
var popupFactory = getSingle(popup);
document.getElementsByTagName('J-popup').onclick = function () {
var popupInstance = popupFactory();
popupInstance.style.display = 'block';
}
要是想创建其他的单例,只用复写popup,然后丢给getSingle就OK啦。
到这里突然想到,实习第一个需求是写一个设计师管理的页面,可以简化成一个通过ajax动态往页面列表里面追加数据的模型,列表的每个item需要添加click事件,在用事件代理的前提下,click事件只需要在第一次渲染列表的时候被绑定一次即可。但是我们不想去判断当前是否第一次渲染列表怎么办,如果借助于jquery,可以给节点绑定one事件:
var bindEvent = function () {
$('.list').one('click', function () {
console.log('click');
});
}
var render = function () {
console.log('渲染列表');
bindEvent();
}
render();
render();
// ......
借助我们刚从实现的getSingle()函数也可以达到同样的效果:
var bindEvent = getSingle(function () {
document.getElementsByTagName('list')[0].onClick = function () {
console.log('click');
}
return true;
});
var render = function () {
console.log('渲染列表');
bindEvent();
}
render();
render();
// ......
ok,但是单例虽好,但不要贪用哦,因为单例多了的话内存占用会很大,就这些啦,明天晚上继续撸策略模式欢迎小伙伴们一起交流^_^
Recommend
-
46
-
35
单例模式可以说是最容易理解的一种设计模式了,当需要某个类仅有一个全局唯一对象时可以使用,比如某些配置项。核心思想就是新建某个类实例时先进行一次判断,如果不存在则创建新实例返回,否则返回已经存在的实例。 懒汉模式(Laz...
-
53
大家好,我是卡二条,很感谢大家关注我的个人微信公众号.为什么写这篇文章呢?主要是因为最近在公司负责架构这一块所遇到的一些问题,所感想而来。 到今天加入现在的团队也整整3个月了,一直负责架构这一块的工作内容,从最开始接手项目...
-
25
-
7
Python 设计模式——单例模式 2020-11-27 ...
-
19
Go设计模式:单例模式、原型模式和Builder模式 这篇文章记录三个设计模式,因为他们都比较简单,因此较短的篇幅就可以描述完,就把这三个放在一起。 单例模式,就是为了确保全局唯一。在Go语言里实现单例模式,好像也没啥好办法,一般就是...
-
20
精读《设计模式 - Singleton 单例模式》前端开发话题下的优秀回答者Singleton(单例模式)Singleton(单例模式)属于创建型模式,提供一种对象获取方式,保证在一...
-
11
23种设计模式 - 单例模式 1.关于单例模式的一些说明 单例模式:确保一个类最多只有一个实例,提...
-
23
设计模式:单例模式 https://xueqiu.com/9777995541... https://xueqiu.com/9777...
-
5
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK