单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点
比如vuex、window对象、线程池

1. 实现单例模式

1.1 基于闭包实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Singleton (name) {
this.name = name;
}

Singleton.prototype.getName = function () {
console.log(this.name);
}

Singleton.getInstance = (function () {
let instance = null;
return function (name) {
if (!instance) {
instance = new Singleton(name);
}
return instance;
}
})();

let a = Singleton.getInstance('liang1');
let b = Singleton.getInstance('liang2');

console.log(a === b); // true

1.2 利用代理模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let ProxySingleton = (function () {
let instance;
return function (name) {
if (!instance) {
instance = new Singleton(name);
}
return instance;
}
})();

let c = new ProxySingleton('liang1');
let d = new ProxySingleton('liang2');

console.log(c === d); // true

利用代理模式来解耦管理单例的逻辑

1.3 通用的惰性单例

1
2
3
4
5
6
function getSingle (fn) {
let result;
return function () {
return result || (result = fn.apply(this, arguments));
}
}

只需要给getSingle传递一个创建实例的fn就能创建单例模式

2. 弹窗实例

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
<body>
<button id="btn">打开弹窗</button>
<script>
// 通用的创建惰性单例模式
function getSingle(fn) {
let result;
return function () {
return result || (result = fn.apply(this, arguments));
}
}

// 创建弹窗并添加到body下,并用getSingle创建单例模式
let createDialog = getSingle(function () {
let div = document.createElement('div');
div.className = "message-box";
div.innerHTML = `
<div class="mask"></div>
<div class="dialog">
<div class="dialog-bd">这是一个弹窗哦</div>
<div class="dialog-ft">
<a href="javascript:" class="dialog-btn">确定</a>
</div>
</div>
`.trim();
div.style.display = "none";
document.body.appendChild(div);
return div;
})

document.getElementById("btn").onclick = function () {
let dialog = createDialog();
dialog.style.display = "block";
}

// 为弹窗按钮绑定关闭事件
document.addEventListener("click", function (event) {
if (event.target.className === "dialog-btn") {
let dialog = createDialog();
dialog.style.display = "none";
}
})
</script>
</body>

getSingle函数通过变量result保存弹窗实例,如果已经存在则直接返回该实例,否则创建弹窗实例,保证了弹窗的唯一性

4du1f-5c1xe

参考

《JavaScript设计模式与开发实战》

作者

Liang

发布于

2021-01-28

更新于

2021-12-25

许可协议


评论