JS设计模式 - 常见7种

68 阅读2分钟

工厂模式

调用函数,返回一个新对象

  • vue3 createApp

单例模式

调用函数,获取单例对象,重复调用获取的是同一个对象

class SingleTon{
   static #instance;
   static getInstance(){
      if(this.#instance === undefined){
        this.#instance = new SingleTon()
      }
      return this.#instance
   }
}
let s1 = SingleTon.getInstance();
let s2 = SingleTon.getInstance();

观察者模式

一个对象状态改变,依赖的对象都会收到通知

image.jpeg

发布订阅模式

和观察者模式类似,但多了一个事件总线,通过事件总线去注册/触发事件

class Emmiter{
    #handler = {};
    $on = (event, fn) => { // 注册事件
      if(this.#handler[event] === undefined){
        this.#handler[event] = []
      }
      this.#handler[event].push(fn)
    }
    $emit = (event, ...args) => { //触发
       const funs = this.#handler[event] || [];
       funs.forEach(fn => {
          fn(...args)
       });
    }
    $off = (event) => { //移除
        this.#handler[event] = undefined;
    }
    $once = (event, fn) => { //一次性事件
       this.$on(event, (...args) => {
           fn(...args);
           this.$off(event);
       })
    }
}
const bus = new Emmiter();

原型模式

复制一个已存在的实例,返回新的实例

  • Object.create() 对象作为原型,创建新对象
  • vue2的数组方法,对数组方法进行包裹,可以更新视图

代理模式

控制对数据/对象的操作(访问...)

image.jpeg 缓存代理

  1. 创建对象缓存数据
  2. 判断是否有缓存数据
  3. 没有缓存 - 查询,缓存,返回
  4. 有缓存 - 直接返回

迭代器模式

通过接口,可以访问容器中的每一个元素(遍历)

for in 和 for of

  1. for in
  • 可以遍历对象除[symbol]以外的可枚举属性
  • 遍历的是索引
  • 继承来的属性也可以遍历

image.png 2. for of

  • 遍历可迭代对象,Map,Set,Array,String,arguments
  • 遍历的是值
  • 继承来的属性无法遍历
  • 不能遍历对象Object,不可迭代,没有Symbol.iterator方法

image.png

迭代协议

  1. 可迭代协议 对象增加方法[Symbol.iterator] ( ){ ... },返回(符合迭代器协议的)对象
  2. 迭代器协议 是一个对象,有next方法,next方法返回
  • 继续迭代 { done:false, value:'...' }
  • 迭代完成 { done: true }
const obj = {
  [Symbol.iterator](){
    let index = 0;
    let arr = [1,2,3,4]
    return {
        next(){
          if(index < arr.length){
            return { done:false, value:arr[index++] }
          }
          return { done: true }
        }
    }
  }
}

使用generator函数

const obj = {
   [Symbol.iterator](){
      function* funGenerator(){
         yield 'a'
         yield 'b'
      }
      const gen = funGenerator();
      return gen
   }
}