实现观察者模式
我们希望实现的调用方式是这样的
option.on("click", arr => {
let text = `名字:${arr.name} \n年龄:${arr.age} `
console.log(text)
}) // 添加监听
option.emit("click", { name: "star", age: 23 }) // 触发监听事件
option.off("click") // 移除监听事件
所以下面我们会分为三步走
Step1 如何监听 on
function observer() {
this.handles = {} // 定义一个容纳要监听事件的对像
}
observer.prototype.on = function(type, hander) {
// 在原型上添加on方法
// 为监听的事件添加到监听列表中
if (!this.handles[type]) {
this.handles[type] = []
}
// 将处理函数添加到事件对应的数组中
this.handles[type].push(hander)
}
// 现在我们可以这样添加一个事件
const option = new observer()
option.on("click", arr => {
// 这里是监听到click事件的回调
}) // 添加监听
Step2 如何触发事件 emit
observer.prototype.emit = function() {
// 将参数转换为数组
const arr = [].slice.call(arguments, 0)
// 第一个参数为事件名称
const type = arr[0]
if (this.handles[type]) {
// 如果已经添加监听函数,则触发回调
this.handles[type].forEach(fun => {
fun.apply(this, arr.slice(1))
})
} else {
console.warn(`please add event "${type}" listener first`)
}
}
Step3 如何取消监听的事件 off
observer.prototype.off = function(type) {
if (this.handles[type]) {
delete this.handles[type]
}
}
我们可以向下面一样测试我们实现的观察者模式是否有效
const option = new observer()
option.on("click", arr => {
let text = `名字:${arr.name} \n年龄:${arr.age} `
console.log(text)
}) // 添加监听
option.emit("click", { name: "star", age: 23 }) // 触发监听事件
option.emit("hover") // 触发未监听事件
option.off("click") // 移除监听事件
option.emit("click") // 测试移除后的事件
打印结果如下
名字:star
年龄:23
please add event "hover" listener first
please add event "click" listener first