Js设计模式 - 单例模式实现及应用
1.单例模式解释
单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。
2.应用场景举例
登录页
购物车
vuex
全局loading遮罩
......
3.代码解释
1.通过闭包和立即执行函数实现
var singletonPatten = (function() {
// 单例构造函数
function singleton(arg) {
var arg = arg || {}
this.x = arg.x || 1
this.y = arg.y || 1
}
// 单例实例容器
var instance
return function(arg) {
if(!instance) {
instance = new singleton(arg)
}
return instance
}
}())
var singletonTest1 = singletonPatten({x: 2, y: 7})
var singletonTest2 = singletonPatten()
singleton1.z = 3
console.log(singletonTest1 === singletonTest2) //true
console.log(singletonTest2.x) // 2
console.log(singletonTest2.z) // 3第一次取实例时, 把singleton实例存到instance中,第二次实例已经存在直接返回instance,所以第一次获得的实例和第二次获得的实例是相同的。
2.通过构造函数实现
function Singleton(arg) {
//实例是否已存在
if(typeof Singleton.instance === 'object') {
return Singleton.instance
}
var arg = arg || {}
this.x = arg.x || 1
this.y = arg.y || 1
//缓存实例
Singleton.instance = this
}
var singleton1 = new Singleton({x: 2, y: 2})
var singleton2 = new Singleton()
singleton1.z = 3
console.log(singleton1 === singleton2) //true
console.log(singleton2.x) //2
console.log(singleton2.z) //3获得构造函数实例前先判断instance是否存在,存在则直接返回,否则将构造函数中的this进行缓存,下次取实例可以直接返回第一次获得的实例
3.构造函数重构实现
function Singleton(arg) {
var arg = arg || {}
//缓存实例
var instance = this
this.x = arg.x || 1
this.y = arg.y || 1
//重构构造函数
Singleton = function() {
return instance
}
}
var singleton1 = new Singleton({x: 2, y: 2})
var singleton2 = new Singleton()
singleton1.z = 3
console.log(singleton1 === singleton2) //true
console.log(singleton2.x) //2
console.log(singleton2.z) //3第一次获得实例先将实例缓存到instance中,然后就构造函数进行一个重构,重构后的构造函数直接返回缓存的实例instanceof,第二次获得后便直接返回直接缓存的实例
4.通过class类实现
class Singleton {
constructor(arg) {
var arg = arg || {}
this.x = arg.x || 1
this.y = arg.y || 1
}
static getInstance(arg) {
if(!Singleton.instance) {
Singleton.instance = new Singleton(arg)
}
return Singleton.instance
}
}
var singleton1 = Singleton.getInstance({x: 2, y: 2})
var singleton2 = Singleton.getInstance()
singleton1.z = 3
console.log(singleton1 === singleton2) //true
console.log(singleton2.x) //2
console.log(singleton2.z) //3静态方法getInstance获取类的实例,先判断instance上面是否缓存实例,没有缓存,如果存在直接返回。
4.实际应用场景
实现一个全局loading遮罩框
class Loading {
constructor() {
this.visile = false
}
show() {
if(this.visile) {
console.log('已经展示')
return true
}
this.visile = true
}
hide() {
if(!this.visile) {
console.log('已经隐藏')
return true
}
this.visile = false
}
static getLoadingMask() {
if(!Loading.instance) {
Loading.instance = new Loading()
}
return Loading.instance
}
}上述代码,定义了一个loading遮罩的类,有两个实例方法,show和hide,还有一个静态类getInstanceMask
当两处地方需要获得loading遮罩实例进行操作
var loading1 = Loading.getLoadingMask()
var loading2 = Loading.getLoadingMask()
console.log(loading1 === loading2) //true
loading1.show()
loading1.hide()
loading1.show()
loading2.show() //已经展示
loading2.hide()
loading2.hide() //已经隐藏当对loading1和loading2执行show方法,第二次执行show会报已经展示,表示是同一个laoding遮罩实例
这样就实现了一个单例模式的实际应用场景。
其他的如基于vue的vuex就是最典型的单例模式,因为它的全局状态管理器,只能存在一个,不能多个。
单例模式实际为了节省资源而存在的一种模式,也是很常见的一种模式之一。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!