class Event {
constructor(){
this.events = {}
}
on(type, handler) {
if(!this.events.hasOwnProperty(type)){
this.events[type] = [];
}
this.events[type].push(handler)
return this;
}
emit(type, ...args) {
for(let i = 0; i < this.events[type].length; i++) {
this.events[type][i].apply(this, args)
}
return this;
}
off(type, handler){
if(!this.events.hasOwnProperty(type)){
throw new Error(`不存在${type}`)
}
const len = this.events[type].length
const eventHandler = this.events[type]
for(let i = 0; i < len; i++) {
if(eventHandler[i] == handler){
eventHandler.splice(i, 1)
}
}
return this;
}
once(type, handler){
const on = (...args) => {
handler.apply(this, args)
this.off(type, on)
}
this.on(type, on)
return this;
}
}
const event = new Event()
const a1 = function(data){
console.log(1 + data);
}
// event.on('a', a1);
// event.emit('a', '我是第1次调用的参数');
// event.emit('a', '我是第2次调用的参数');
event.once('b', a1);
event.emit('b', '一次');
event.emit('b', '两次');
// vue中数据劫持结合发布/订阅模式
class Observer {
constructor (value) {
this.value = value
this.dep = new Dep()
this.walk(value)
}
walk (obj) {
const keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i],obj[keys[i]])
}
}
}
function defineReactive (obj, key, value){
const dep = new Dep()
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
console.log('get')
dep.addSub({
update:()=>{
console.log('执行update')
}
});
return value
},
set: function reactiveSetter (newVal) {
if (newVal === value || (newVal !== newVal && value !== value)) {
return
}
console.log('set')
value = newVal;
dep.notify();
}
})
}
class Dep {
constructor (valuey) {
this.subs = [];
}
addSub(sub){
this.subs.push(sub);
}
notify(){
this.subs.forEach(function(sub){
sub.update();
});
}
}
let obj ={a:1,b:2,c:3}
new Observer(obj)
obj.a
obj.a = 2
对发布订阅者的通俗理解
订阅可以理解为寄存,发布理解为寄存的拿出调用,可以寄存很多个,拿出很多个
观察者模式主要是监听