我们要有一个观察者(这里抽象为一个对象 {}
)
需要有一个属性,存放消息的盒子(把你绑定的所有事件放在里面)
需要一个 on 方法,用于添加事件
需要一个 emit 方法,用于发布事件(触发)
需要一个 off 方法,把已经添加的方法取消
// 定义一个class类
class observer {
constructor() {
// 存放消息的盒子,把绑定的所有事件放在里面
this.box = {}
}
// on方法,用于添加事件
on(type, fn) { // type事件类型,fn事件处理函数
// 添加时先判断盒子里有没有这个事件类型
if(!this.box[type]) {
// 如果没有那么需要新增这个类型,当键存储在box对象,键对应的是一个数组,里面是不同的事件函数(相当于多少个订阅的人)
this.box[type] = [fn]
}else {
// 如果已经有了,那么直接把这个事件函数放进数组去(相当于把这个人加进去)
this.box[type].push(fn)
}
}
// emit方法,用于发布事件(就是让订阅好的事件执行)
emit(type, ...arr) { // type事件类型,arr给事件处理函数传递参数,由于不知道会传递多少参数,所以使用...运算符
// 如果box里面压根没有这个事件类型,那就不需要执行了,直接return
if(!this.box[type]) return
// 如果有那么执行事件函数
this.box[type].forEach(item => {
// item() 不改变事件this直接调用
// 调用对应type事件类型,数组里面的方法,顺便改变事件函数内this为当前位置this,并将参数传递入事件函数
item.call(this,arr)
})
}
// off方法,移除事件函数
off(type, fn) { // type事件类型,fn事件处理函数
// 如果压根没有这个事件类型,删除个毛,直接return
if(!this.box[type]) return
// 如果有这个事件类型,遍历事件类型对应的数组
for(let i=0; i<this.box[type].length; i++) {
// 如果数组中有需要删除的事件函数
if(this.box[type][i] == fn) {
// 使用数组的splice删除i下标开始的1个数据
this.box[type].splice(i,1)
}
}
}
// clear方法,删除一类数据
clear(type) { // type事件类型
// 如果压根没有这个事件类型,删除个毛,直接return
if(!this.box[type]) return
// 直接删除box的type键
delete this.box[type]
}
// empty方法,清空数据
empty() {
if(this.box) this.box = {}
}
}
// 使用观察者模式操作
var obs = new observer() // 实例化对象
// 准备传入的事件处理函数
function f1(a) {
console.log('hello')
}
function f2(a) {
console.log('world')
}
function f3(a) {
console.log(a)
}
function f4(a) {
console.log(a)
}
// 订阅事件
obs.on('ssr',f1)
obs.on('sr',f2)
obs.on('ssr',f3)
obs.on('sr',f4)
// 发布事件
obs.emit('ssr',100,200,300)
obs.emit('sr',400,500,600)
// 移除事件函数
obs.off('ssr',f1)
obs.off('sr',f4)
// 删除一类数据
obs.clear('ssr')
// 清空数据
obs.empty()