What-什么是单例模式
一个类只有单独的一个实例
Why-为什么要用单例模式
若重复创建不同的实例, 会导致全局管理数据/状态的丢失/混乱
Where-哪里用到单例模式
Vuex
let Vue // bind on install
// ...
export function install (_Vue) {
if (Vue && _Vue === Vue) {
if (process.env.NODE_ENV !== 'production') {
console.error(
'[vuex] already installed. Vue.use(Vuex) should be called only once.'
)
}
return
}
Vue = _Vue
applyMixin(Vue)
}
How-如何实现单例模式
ES5
静态方法与闭包实现
function SingletonClass () {}
SingletonClass.getInstance = (function() {
var instance
return function () {
if (instance === undefined) {
instance = new SingletonClass()
}
return instance
}
})()
const s1 = SingletonClass.getInstance()
const s2 = SingletonClass.getInstance()
console.log(s1 === s2) // true
构造函数return实现
function SingletonBase () {}
function SingletonClass () {
if (SingletonBase.instance === undefined) {
SingletonBase.instance = new SingletonBase()
}
return SingletonBase.instance
}
const s1 = new SingletonClass()
const s2 = new SingletonClass()
console.log(s1 === s2) // true
ES6
class SingletonClass {
constructor() {
if (SingletonClass.Instance === undefined) {
SingletonClass.Instance = this
}
return SingletonClass.Instance
}
}
const s1 = new SingletonClass()
const s2 = new SingletonClass()
console.log(s1 === s2) // true
TypeScript
构造函数return实现
class SingletonClass {
private static instance: SingletonClass
constructor () {
if (SingletonClass.instance === undefined) {
SingletonClass.instance = this
}
return SingletonClass.instance
}
}
const s1 = new SingletonClass()
const s2 = new SingletonClass()
console.log(s1 === s2) // true
装饰器实现
// 单例装饰器, 接收原始构造器
function singleton (rawConstructor: Function) {
let instance
// 新构造器
const newConstructor: any = function (...args) {
// 辅助构造器
const assistConstructor: any = function assistConstructor () {
return rawConstructor.apply(this, args)
}
// 继承原型属性和方法
assistConstructor.prototype = rawConstructor.prototype
if (instance === undefined) {
instance = new assistConstructor()
}
return instance
}
// 继承原型属性和方法
newConstructor.prototype = rawConstructor.prototype
// 返回新构造器, 它将覆盖原构造器
return newConstructor
}
@singleton
class SingletonClass {}
const s1 = new SingletonClass()
const s2 = new SingletonClass()
console.log(s1 === s2) // true