JS设计模式---单例模式、发布订阅模式

本文深入探讨JavaScript中的两种重要设计模式——单例模式和发布订阅模式。单例模式确保一个类只有一个实例,并提供全局访问点。发布订阅模式则通过事件中心实现对象间的解耦通信,允许发送者和接收者无需直接交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JS设计模式--单例模式
    定义 : 无论实例化多少次对象,永远返回第一次的实例对象
一:不使用单例模式
// 定义一个构造函数,然后创建一个实例对象
class Dialog{
    constructor(){
        this.odiv = document.createElement('div')
        console.log('创建一个div元素');
    }
}
let d1 = new Dialog()
console.log(d1);
let d2 = new Dialog()
console.log(d2);
console.log(d1 == d2);
//输出结果如下

 

二:使用单例模式:
//需求:创建多个实例对象的时候,要想每次只执行一次costructor,每次new出来的都是同一个实例,这样就创建了一个div
//创建自调用函数,避免全局污染
let singleFun = (function(){
        //instance避免全局污染,相对于外层函数为局部变量,使用闭包将instance局部变量返回,相对于内层函数为全局变量,内层函数也可以使用instance
        let instance = null;   //null为false
        class Dialog{
            constructor(){
                this.odiv = document.createElement('div')
                console.log('创建一个div元素');
            }
            //原型对象上的方法
            init(title){
                this.title = title
            }
        }
    //防抖节流,singleFun就是执行的以下闭包函数
        return function(title){
            //if该处的代码只执行第一次(为空)
            if(!instance){     //!null为true
                //说明当前没有实例,为空,创建一个实例
                instance = new Dialog(title)
            }
            //return返回上一次的实例,执行多次
            //实现实例中的内容不一样,用实例对象调用原型对象上的方法
            instance.init(title)
            return instance
        }
    }
)()
let d1 = singleFun('添加')
//调用singleFun()执行return函数,全局变量instance第一次为空,执行(!instance),创建一个实例
console.log(d1);    //输出第一次的实例对象
let d2 = singleFun('删除')
//调用singleFun()执行return函数,因为第一次已经创建一个实例,所以instance不为空,执行return,直接返回instance上一次的实例
console.log(d2);    //返回上一次的实例
console.log(d1 == d2);
//输出结果如下

 

JS设计模式--发布订阅模式<观察者模式>
    vue2实现数据绑定原理 :数据劫持+发布订阅模式
    vue3实现数据绑定原理 :proxy + 发布订阅模式
    JS中也使用发布订阅模式
    最常用的例子 :事件绑定的实现
    语法 :元素.addEventListener('事件',执行函数)
例如:买书
    元素---书店老板boss
    事件---书   不同的事件意味着有不同的书
    执行函数---谁买书(张三买,李四买,...等等)
class Boss{
    constructor(){
        this.messages = {}  //比作 用来记录书和对应买书的人的本
    }
   
    给本上添加记录{
        书名1:[张三买,李四买,...]
        书名2:[张五买,李六买,...]
    }
    //给本上添加记录
    add(type , fn){
        //type表示当前这本书
        //fn表示都有谁买这本书
        //首先判断当前本上有没有记录这本书
        if(!this.messages[type]){
            this.messages[type] = [];
            this.messages[type].push(fn)
            //当前表示:{书名1:[谁买]}
        }
        //如果本上有这本书,说明之前已经有人预定过,记录时不能重复,所以进行判断
        if(this.messages[type].indexOf(fn)== -1){
            this.messages[type].push(fn)
        }
    }
    //删除本上记录
    remove(type , fn){
        //先判断当前本上是否记录这本书
        if(this.messages[type]){
            //记录过,删除时,先判断是删除这本书,还是删除这本书里面对应的买书人
            if(!fn){
                //情况一:删除这本书,删除messages对象上的数据type
                delete this.messages[type]
            }else{
                //情况二:有type和fn两个参数,说明要删除对应的买书人
                this.messages[type]=this.messages[type].filter(item => {return item !== fn})
            }
        }
    }
    //通知买书
    tritter(type){
        //先判断有没有这本书的记录
        if(this.messages[type]){
            this.messages[type].forEach((item)=>{
                item()
            })
        }
    }
}
//创建书店老板
let boss = new Boss();
console.log(boss);
//老板给本上添加记录,书名:[买书人1,买书人2,..]
function zhangsan(){
    console.log('张三买书');
}
function lisi(){
    console.log('李四买书');
}
function wangwu(){
    console.log('王五买书');
}
//给本上添加记录
boss.add('book1' , zhangsan)
boss.add('book1' , lisi)
boss.add('book2' , zhangsan)
boss.add('book3' , wangwu)
//删除本上记录
//1、直接删除书
boss.remove('book2')
//2、删除买书的人
boss.remove('book1' , lisi)
//通知买书
boss.tritter('book1')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值