持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
单例模式,即对一个 class 只能创建一个实例。
使用ts实现单例模式
class Singleton {
// private - 外部无法初始化,即无法使用new Singleton来创建实例
private constructor() { }
// 加上private 在外面不能使用Singleton.instance来访问,只能通过Singleton.getInstance来访问实例
private static instance: Singleton | null
static getInstance(): Singleton {
// 这里也可以写 `this.instance`,static下的this指向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
使用js实现单例模式
使用闭包
function genGetInstance() {
let instance // 闭包
class Singleton {}
return () => {
if (instance == null) {
instance = new Singleton()
}
return instance
}
}
const getInstance = genGetInstance()
const s1 = getInstance()
const s2 = getInstance()
使用模块化
let instance // 闭包
class Singleton {}
// 外部只能 import 这个函数
export default () => {
if (instance == null) {
instance = new Singleton
}
return instance
}
其实使用模块化来实现单例,也是使用了闭包,因为模块化之后也会在模块外包裹一层函数。
登录框: 单例模式
class LoginForm {
private state: string = 'hide'
private constructor() {}
show() {
if (this.state === 'show') {
console.log('已经显示了')
return
}
console.log('显示 LoginForm')
// 操作dom 显示登录框
// ....
this.state = 'show'
}
hide() {
if (this.state === 'hide') {
console.log('已经隐藏了')
return
}
console.log('隐藏 LoginForm')
// 操作dom 隐藏登录框
// ....
this.state = 'hide'
}
private static instance: LoginForm | null = null
static getInstance(): LoginForm {
if (!this.instance) {
this.instance = new LoginForm()
}
return this.instance
}
}
const loginForm1 = LoginForm.getInstance()
const loginForm2 = LoginForm.getInstance()
前端用到严格的单例模式并不多,但单例模式的思想到处都有:
- 自定义事件 eventBus 全局只有一个
- Vuex Redux store 全局只有一个