js设计模式之观察者模式

本文介绍了观察者模式和发布订阅者模式的区别,并通过JavaScript代码展示了如何实现这两种模式。通过监听input框输入值的变化,动态高亮显示对应的字母或数字。接着,文章用面向对象的方式重构了代码,创建了`Input`类和两个子类`Observer`、`Alphabet`及`Num`,实现了更抽象和模块化的代码结构。
摘要由CSDN通过智能技术生成

什么是观察者模式?

        观察者模式是一对多的一种依赖关系,让多个观察者对象同时监听某一个主体对象。这个主体发生状态的时候。会通知所有的观察者对象,自动更新自己的状态。

        而发布订阅者模式,则不同。发布订阅者模式是一种多对多的依赖关系。通过事件的绑定,通知给需要接受的订阅者,让订阅者更新自己的状态。

        两种之间的区别在于观察者模式知道自己所派发的目标对象是谁。而发布订阅者模式观察者和订阅者之间不清楚对方是谁。是由中间层进行交互完成派发任务。

写一个通过输入对应的字母的案例

<body>
    <input>
    <p>A</p>
    <p>B</p>
    <p>C</p>
    <p>数字</p>
</body>

通过input框中输入的值。通过addEventListener来监听每次输入的值来是否让对应的字母进行高亮显示。

<script>
    let inp = document.querySelector('input')
    var A = document.querySelector('#A');
    var B = document.querySelector('#B')
    var C = document.querySelector('#C')
    var num = document.querySelector('#num')
    
    inp.addEventListener('input', function () {
        A.classList.toggle('active', this.value.indexOf('A') !== -1)
        B.classList.toggle('active', this.value.indexOf('B') !== -1)
        C.classList.toggle('active', this.value.indexOf('C') !== -1)
        num.classList.toggle('active', /\d/.test(this.value))
    })
</script>

那么接下来通过面向对象的方式,将这块重新编写一边。

<script>
    class inp {
        // 在构造函数里面编写属性
        constructor(el) {
            this.observers = [];
            // 通过监听input框的变化将变化的值传给所有的观察者
            el.addEventListener('input', (e) => {
                this.allNotify(e.target.value)
            })
        }
        allNotify(value) {
            this.observers.forEach(item => {
                item.notify(value)
            })
        }
        addObserver(ob) {
            this.observers.push(ob)
        }
    }

    // DocumentFragment对象 一般动态创建html元素都需要创建好添加到html会导致页面回流,
    // DocumentFragment对象是通过一次性将子孙节点添加进。因此性能会有效的提高
    class observer extends DocumentFragment {
        constructor(txt) {
            super()
            // 在每次new一个的时候创建对应的节点
            this.p = document.createElement('p');
            this.p.innerHTML = txt
            document.querySelector('body').append(this.p)
        }
        // 通过匹配到对应的字符出现对应的方法
        notify(value) {
            this.p.classList.toggle('active', this.handle(value))
            console.log(this.handle(value));
        }
    }


    class alphabet extends observer {
        constructor(txt) {
            super(txt)
            this.txt = txt
        }
        handle(value) {
            // 当每次变化的值indexOf不为-1说明有相对应的值
            return value.indexOf(this.txt) !== -1
        }
    }

    class num extends observer {
        constructor(txt) {
            super(txt)
            this.txt = txt
        }
        handle(value) {
            // 通过正则来判断是否有数字
            return /\d/.test(this.txt)
        }
    }
    const inpK = new inp(document.querySelector('input'));
    inpK.addObserver(new alphabet('A'))
    inpK.addObserver(new alphabet('B'))
    inpK.addObserver(new alphabet('C'))
    inpK.addObserver(new num('数字'))
</script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值