8 单例模式 – 前端设计模式系列教程

介绍
  • 系统中被唯一使用
  • 一个类只有一个实例
示例
  • 登录框 (整个系统唯一的一个实例)
  • 购物车 (唯一)
示例代码
class SingleObject{
    login(){
        console.log('login...')
    }
}
SingleObject.getInstance = (function(){
    let instance
    return function (){
        if (!instance){
            instance = new SingleObject()
        }
        return instance
    }
})()

let obj1 = SingleObject.getInstance()
obj1.login() //login...

let obj2 = SingleObject.getInstance()
obj2.login() //login...

console.log('obj1 ===obj2',obj1 ===obj2) //obj1 ===obj2 true

console.log('----分割线------')

let obj3 = new SingleObject() // 无法完全控制
obj3.login() //login...
console.log('obj1 === obj3', obj1===obj3) //obj1 === obj3 false

 

应用场景
jQuery
如果没有单例模式的话,不同的页面引用了jQuery,会被重复初始化多次,很容易导致jQuery的某个方法被重复执行了两次或多次的bug。
// jQuery的单例模式,确保juqery 只有一个$
if(window.jQuery != null){
    return window.jQuery
}else{
    // 初始化
}

 

登录框
整站只有唯一的一个登录框,尤其是登录框作为一个弹出层组件的时候引用,特别适合使用单例模式
class LoginForm {
    constructor (){
        this.state = 'hide'
    }
    show(){
        if(this.state === 'show'){
            alert('已经显示')
            return
        }
        this.state = 'show'
        console.log('登录框显示成功')
    }
    hide(){
        if(this.state === 'hide'){
            alert('已经隐藏')
            return
        }
        this.state = 'hide'
        console.log('登录框隐藏成功')
    }
}
// 单例模式,通过一个自执行函数形成闭包保护私有变量,避免造成全局污染
LoginForm.getInstance = (function(){
    let instance 
    return function(){
        if(!instance){
            instance = new LoginForm()
        }
        return instance
    }
})()

let login1 = LoginForm.getInstance()
login1.show() //登录框显示成功

let login2 = LoginForm.getInstance()
login2.hide() //登录框隐藏成功
login1.hide() //已经隐藏

 

购物车
全局购物车,类似登录框。还有vuex和redux的store道理也是一样
设计原则验证
  • 符合单一职责原则,只能实例化唯一的对象
  • 没法具体体现开放封闭原则,但是绝对不会违反开放封闭原则

本站文章如未注明均为原创 | 文章作者:刘晓帆 | 转载请注明来自:前端印象

发表评论

邮箱地址不会被公开。 必填项已用*标注

浏览量:18 次浏览