SOURCE

class Observer {
    constructor() {
        this._listener = {}
    }
    on(type, fn) {
        if (!this._listener[type]) {
            this._listener[type] = []
        }
        this._listener[type].push(fn)
    }
    off(type, fn) {
        let events = this._listener[type]
        events.forEach((event, index) => {
            if(event == fn) {
                events.splice(index, 1)
            }
        })
    }
    trigger(type, ...args) {
        let events = this._listener[type]

        events.forEach(fn => {
            fn(...args)
        })
     }
}

var ob = new Observer()
var obj = {
    name: 'lao wang',
    say() {
        console.log(this.name)
    }
}

var fn1 = obj.say.bind(obj)

ob.on('haha', fn1)
// ob.off('haha', fn1)
ob.on('haha', (name) => {
    console.log(`haha:${name}`)
})



ob.trigger('haha', 'lao li')
console 命令行工具 X clear

                    
>
console