设计模式-singleton-js

前言

张肖飞在暑假放假前给我说:“你要好好准备面试了,比如我之前面试的时候面试官问我什么是单例模式,那你面试前端肯定也会问你js里的单例模式。”

我:“啥是单例模式???”

单例模式

定义

单例对象的类必须保证只有一个实例存在,提供一个全局访问点。

解决的问题

一个全局使用的类频繁的创建与销毁。

何时使用

想控制实例数目,节省系统资源的时候。

如何解决

判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

应用场景

线程池,全局缓存等。 window 对象就是一个单例。这种只需要一个对象的就用单例模式。

简单实现(js)

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

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

// 获取实例对象
var getInstance = (function() {
var instance = null;
return function(name) {
if(!instance) {
instance = new Singleton(name);
}
return instance;
}
})();

// 测试单例模式的实例
var a = getInstance("aa");
var b = getInstance("bb");
console.log(b.getName()); // "aa"
console.log(a === b); // true

封装一个获取实例的模块

1
2
3
4
5
6
7
// 获取实例的封装代码
var getInstance = function(fn) {
var result;
return function(){
return result || (result = fn.call(this,arguments));
}
};

ES5实现,封装一个函数,作为一个对象返回,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function StorageSingleton () {}
StorageSingleton.prototype.getItem = function (key){
return localStorage.getItem(key)
}
StorageSingleton.prototype.setItem = function (key, value) {
return localStorage.setItem(key, value)
}

var Storage = (function(){
var instance
return function(){
return instance || instance = new StorageSingleton()
}
})()
var a = new Storage()
var b = new Storage()
a === b // true
a.setItem('a','a')
b.getItem('a') // 'a'

ES6原生加入了class的语法糖,这样的写法和其他语言的类构造方法相似

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Storage {
constructor(){
if(!Storage.instance){
Storage.instance = this
}
return Storage.instance
}
getItem (key) {
return localStorage.getItem(key)
}
setItem (key, value) {
return localStorage.setItem(key, value)
}
}
let a = new Storage()
let b = new Storage()
a === b // true
a.setItem('a','a')
b.getItem('a') // 'a'

reference

JS单例模式实现ES5/ES6

单例模式

jS设计模式二:单例模式