相信你們對發佈訂閱確定很熟悉吧,不少場景都應用到了發佈訂閱;數組
例如自定義的一些事件,經過自定義的‘事件’,經過某個點觸發;promise
例如:promise的原理其實和發佈訂閱也有一些的關係;將成功,失敗,或者的必須作的函數分別放在數組中,當promise返回成功時,則把成功的函數事件所有都發布出去;app
今天我給你們寫個發佈訂閱的event.js ;相信有去看各類插件源碼均可以看到這個文件函數
function Event(){ this._events={}; } Event.prototype.on = function (type, fn, context = this) { if (!this._events[type]) { this._events[type] = [] } this._events[type].push([fn, context]) } Event.prototype.once = function (type, fn, context = this) { function magic() { this.off(type, magic) fn.apply(context, arguments) } // To expose the corresponding function method in order to execute the off method magic.fn = fn this.on(type, magic) } Event.prototype.off = function (type, fn) { let _events = this._events[type] if (!_events) { return } let count = _events.length while (count--) { if (_events[count][0] === fn || (_events[count][0] && _events[count][0].fn === fn)) { _events[count][0] = undefined } } } Event.prototype.trigger = function (type) { let events = this._events[type] if (!events) { return } let len = events.length let eventsCopy = [...events] for (let i = 0; i < len; i++) { let event = eventsCopy[i] let [fn, context] = event if (fn) { fn.apply(context, [].slice.call(arguments, 1)) } } }
demo:this
var bs=new Event(); bs.on('click',function(){console.log(111)},window); var aaa=333; bs.on('click',function(){console.log(this.aaa)},window); bs.once('click',function(){console.log('once')},window); console.log(bs._events) bs.trigger('click') console.log(bs._events) bs.trigger('click') console.log(bs._events)
結果截圖:spa