js设计模式-行为型:策略模式、观察者模式、事件委托、职责链模式、模板方法模式、迭代器模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

134 阅读2分钟

一、策略模式

事先将各种情况列举出来,在使用时不用做if else逻辑判断,直接通过对象调取

二、观察者模式

别名:订阅发布模式

      class Email {
        constructor() {
          this.emailList = []
        }
        // 发布
        publish() {
          for (const item of this.emailList) item.receive('明天不上班')
        }
        // 订阅
        subscribe(item) {
          this.emailList.push(item)
        }
        // 退订
        remove(item) {
          const index = this.emailList.indexOf(item)
          this.emailList.splice(index, 1)
        }
      }

      class Person {
        constructor(name) {
          this.name = name
        }
        receive(msg) {
          console.log(`${this.name}接收到邮件消息为${msg}`)
        }
      }

      const email = new Email()

      const zhangsan = new Person('zhangsan')
      const lisi = new Person('lisi')

      email.subscribe(zhangsan)
      email.subscribe(lisi)

      email.publish()

      email.remove('lisi')

      email.publish()

js事件就是发布订阅模式

      function fn1() {
        console.log('点击body-fn1')
      }
      function fn2() {
        console.log('点击body-fn2')
      }
      // 订阅
      document.body.addEventListener('click', fn1)
      document.body.addEventListener('click', fn2)

      // 发布
      document.body.click()

三、事件委托

  1. 事件委托是将事件的触发由当前元素绑定到其父元素身上。事件委托可以在页面的任何生命周期添加事件处理程序,而不同等到DOMContentloaded完成后。事件委托可以对内存占用减小,对于DOM的访问减少
  2. 事件能够委托的前提是目标元素(e.target)是支持事件冒泡的,事件默认都是支持冒泡的,就怕被改了
  3. 事件委托不要滥用,如果事件委托的层级过多,某一层的冒泡过程被阻止了(e.stopPropagation()),那么会导致事件委托失败。如果所有的事件都用委托,会导致事件之间的逻辑关系错乱,一些不需要被触发的事件也会被绑定

原生js事件委托

    <ul>
      <li>第一行</li>
      <li>第二行</li>
      <li>第三行</li>
      <li>第四行</li>
    </ul>
    <script>
      const ul = document.querySelector('ul')
      ul.addEventListener('click', clickHandler)
      function clickHandler(e) {
        if (e.target.nodeName !== 'LI') return
        const arr = [...ul.children]
        const index = arr.indexOf(e.target)
        const text = arr[index].innerHTML
        console.log(index + text)
      }
    </script>

vue中事件委托:通过自定义属性

    // handleClick方法不传参,默认传的是e;如果还需要额外传别的参数,得这样写handleClick($event,1020)
    <ul @click="handleClick">
      <li v-for="item of ['a','b','c']" :key="item" :data-item='item'>{{item}}</li>
    </ul>
    
    handleClick(e) {
      console.log(e.target.dataset)
      console.log(e.target.getAttribute('data-item'))
    }

四、职责链模式

将一个大的任务拆分成若干个小任务,每个人完成各自的任务即可