SOURCE

// 版本二(优化)
// 观察者设计模式(发布订阅模式)
let event = {
  list: [],
  listen: function(key, fn) {
    if(!this.list[key]) { // 如果没有 就给一个初始列表
      this.list[key] = [];
    }
    shopObj.list[key].push(fn); // 往特定的商品列表中添加订阅
  },
  publish: function() {
    let key = arguments[0];
    let fns = this.list[key]; // 往特定的列表(订阅了该型号的用户数组)添加发布消息
    for(let i=0, fn; fn = fns[i++];) {
      // 执行订阅的fn arguments: js内置对象,存储所有的实参
      fn.apply(this, arguments);
    }
  }
}
// 观察者对象初始化
let initEvent = function (obj) {
  for (let i in event) {
    obj[i] = event[i]; // 所有event的属性进行一个拷贝
  }
}
// 发布者
let shopObj = {};
initEvent(shopObj); // 给发布者event的所有属性,shopObj就能操作所有方法

// A添加订阅
shopObj.listen('huawei', function(brand, model){
  console.log(`A订阅: ${brand}的${model}`);
})
// B添加订阅
shopObj.listen('apple', function(brand, model){
  console.log(`B订阅: ${brand}的${model}`);
})
// 商家发布消息
shopObj.publish('huawei', 'P30');
shopObj.publish('apple', 'iphone 12');
console 命令行工具 X clear

                    
>
console