javascript 中常用的几种设计模式

记录下js中比较常用的设计模式

单例模式

单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Singleton{
constructor(name){
this.name = name
this.instance = null
}
static getInstance(name){
if(!this.instance){
this.instance = new Singleton(name)
}
return this.instance
}
getName(){
console.log(this.name)
}
}
var a = Singleton.getInstance('sven1');
var b = Singleton.getInstance('sven2');
// a 和 b 指向同一个实例
console.log(a===b) // true

发布订阅模式

发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状
态发生改变时,所有依赖于它的对象都将得到通知。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class EventTarget {
constructor() {
this.handlers = {};
}
// 添加订阅
addHandler(type, handler) {
if (typeof this.handlers[type] == "undefined") {
this.handlers[type] = [];
}
this.handlers[type].push(handler);
}
// 执行
fire(type) {
var handlers = this.handlers[type];
if (!handlers) return;
for (var i = 0, len = handlers.length; i < len; i++) {
handlers[i]();
}
}
// 移除订阅
removeHandler(type) {
if (this.handlers[type] instanceof Array) {
delete this.handlers[type];
}
}
}
var ex = new EventTarget();
// 添加订阅者
ex.addHandler('work', function () {
console.log('work')
})
ex.addHandler('search', function () {
console.log('search')
})
ex.addHandler('come', function () {
console.log('come')
})
ex.addHandler('work', function () {
console.log('work222')
})
ex.addHandler('work', function () {
console.log('work3333')
})
// 发布消息
ex.fire('work');
ex.fire('search');
// 执行打印
work
work222
work3333
search

代理模式

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

这个模式比较常用,比如事件订阅中的事件委托。

每个子列表都监听点击事件会非常消耗性能,一般的做法是把点击事件的监听放在外层的父元素上面.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<ul id="box">
<li>的借款方聚少离多</li>
<li>的借款方聚少离多</li>
<li>的借款方聚少离多</li>
<li>的借款方聚少离多</li>
<li>的借款方聚少离多</li>
<li>的借款方聚少离多</li>
<li>的借款方聚少离多</li>
</ul>
var box = document.querySelector('#box');
box.addEventListener('click',function(e){
if(e.target && e.target.nodeName.toUpperCase() === 'LI'){
console.log(e.target.nodeName)
}
})

装饰者模式

装饰者提供比继承更有弹性的替代方案。 装饰者用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数)。

装饰者用于通过重载方法的形式添加新功能,该模式可以在被装饰者前面或者后面加上自己的行为以达到特定的目的。

如下面的例子, 在不改变原对象的基础上,不断增加新的功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var plane = {
fire: function () {
console.log('发射子弹');
}
}
plane.fire();
// 增加发射散弹功能
var fire1 = plane.fire;
var shot = function () {
console.log('发射散弹');
}
plane.fire = function () {
fire1();
shot();
}
plane.fire();
// 增加发射跟踪导弹功能
var fire2 = plane.fire;
var track = function () {
console.log('发射跟踪导弹');
}
plane.fire = function () {
fire2();
track();
}
plane.fire();

另外还有其他各种模式,例如:策略模式、组合模式、迭代器模板、适配器模式等等,更多内容可以查看设计模式相关的书籍。

这篇文章大部分模式定义参考的是《javascript设计模式与开发实践》这本书,通俗易懂的一本书,适合初学者。

显示 Gitment 评论