介绍
- 一个对象/实例 只能被创建一次
- 创建之后缓存起来,以后继续使用
- 即,一个系统中只有一个
示例
- 登录框,遮罩层,一个系统只有一个即可,多了无用
- Vuex Redux的store,一个系统中只能有一个,多了会出错
UML类图
示例代码
使用TS特性
- static 静态属性和方法(不能在类的实例上调用静态方法,而应该通过类本身调用)
- private 外部无法直接初始化
class Singleton{
//private -外部无法初始化
private constructor(){}
//static 属性
private static instance:Singleton | null
//static 方法
static getInstance():Singleton {
if(Singleton.instance == null){
Singleton.instance = new Singleton()
}
return Singleton.instance
}
}
//const s1 = new Singleton() // 直接初始化会报错
//Singleton.instance //直接访问instance 也会报错
//创建实例
const s1 = Singleton.getInstance()
const s2 = Singleton.getInstance()
console.log(s1 === s2) //true
不使用TS
function getGenInstance () {
let instance //闭包
class Singleton{ }
return () => {
if(instance == null) {
instance = new Singleton()
}
return instance
}
}
const getInstance = getGenInstance()
const s1 = getInstance()
const s2 = getInstance()
console.log(s1 === s2) // true
- 符合开放封闭原则,对扩展开放,对修改封闭
- 内部封装getInstance,内聚,解耦
使用场景
- 自定义事件 EventBus 全局唯一
- Vuex Redux 的store 全局唯一
注意事项
- JS是单线程语言,如果是java等多线程语言,单例模式需要加线程锁
- 前端对单例模式并不常用,但单例的思想随处可见