js实现 单例模式,观察者模式,发布订阅者模式

84 阅读1分钟

单例模式:

class一个类只有一个实例。 如果已经创建过实例,则直接返回该实例,

//单例模式
class Singleton {
  constructor(name) {
    //判断是否已经创建过实例
    //如果已经创建过实例,则直接返回该实例
    if (!Singleton.instance) {
      Singleton.instance = this;
    }
    this.name = name;
    return Singleton.instance;
  }
}
export defaul

观察者模式:

在js中用proxy代理的时候,每次该表触发set,在set内通知改变。 一对多,一处改变观察者都更新

// 注册观察者
const observe = fn => queuedObservers.add(fn);
// 通知观察者
const observable = obj => new Proxy(obj, {
    //在修改代理对象时被触发
    set(target, key, value, receiver) {
        // Reflect对象,它提供对对象操作的静态方法
        //Reflect.set() 方法来设置属性的值,该方法会调用原始对象的 set 行为,实现对对象属性的设置。
        const result = Reflect.set(target, key, value, receiver);
        // 通知观察者
        queuedObservers.forEach(observer => observer());
        return result;
    }
});

发布订阅者模式:

订阅:订阅者通过关键字,把订阅函数存入经纪人。发布:发布把经纪人内此关键字内的函数都执行。删除:删除经纪人内的相关函数

class Observer {
    caches = {}; // 事件中心

    // eventName事件名-独一无二, fn订阅后执行的自定义行为
    on(eventName, fn) {
        //初始化缓存
        this.caches[eventName] = this.caches[eventName] || [];
        //订阅
        this.caches[eventName].push(fn);
    }

    // 发布 => 将订阅的事件进行统一执行
    emit(eventName, data) {
        if (this.caches[eventName]) {
            this.caches[eventName]
                .forEach(fn => fn(data));
        }
    }
    // 取消订阅 => 若fn不传, 直接取消该事件所有订阅信息
    off(eventName, fn) {
        if (this.caches[eventName]) {
            const newCaches = fn
                ? this.caches[eventName].filter(e => e !== fn)
                : [];
            this.caches[eventName] = newCaches;
        }
    }

}

ob = new Observer();

l1 = (data) => console.log(`l1_${data}`)
l2 = (data) => console.log(`l2_${data}`)

ob.on('event1', l1)
ob.on('event1', l2)

//发布订阅
ob.emit('event1', 789)
// l1_789
// l2_789

// 取消,订阅l1
ob.off('event1', l1)

ob.emit('event1', 567)