标签:
如题,这两基本是一个东西,Event是绑在对象上的,PubSub针对全局。
使用Event完全可以代替PubSub的工作。我就这么干过,比如 export default new Miku.Event()
所以说只要妹妹(Event)就可以了,并不需要姐姐(PubSub)!
一个Event对象
const Event = { evs:{} ,on(s,f){ return !this.evs[s] ?this.evs[s]=[f]: this.evs[s].push(f); } //.. }; const o = {}; Object.assign(o,Event); o.on(‘miku-miku-miku‘,_=>{});
最初用这种模式的时候,我就是用的上面那代码。但这么做evs对象就暴漏了出来,没法保证evs对象不被覆盖,这会产生冲突!
我们可以对这个对象加一层闭包,在Event对象相关方法的作用域中添加一个变量。
const MxEvent = o=>{ const evs = Object.create(null); const Event = { on(s,f){ return !evs[s] ?evs[s]=[f]: evs[s].push(f); } //... }; return Object.assign(o,Event); }
现在这样子基本没问题了。。但还是有坑,如果这个o对象被用作了原型对象,或者用作了assign的target,那么它的相关Event绑定的事件也被继承了下去,订阅的事件就混在一起了!
所以Event相关方法要是不可枚举的 ,最终这么写。
const MxEvent = o=>{ const evs = Object.create(null); return Object.defineProperties(o , { on : { value(s,f){ return !evs[s] ?evs[s]=[f]: evs[s].push(f); } ,writable:true } //... }) } const o = MxEvent({}); o.on(‘miku-miku-miku‘,_=>_); const o2 = MxEvent(Object.assign(o,{b:‘b‘})); //并不会对o发布 o2.trigger(‘miku-miku-miku‘);
我代码没写全,trigger不想写了(实现很简单)。。上面这段代码仅针对es5+的浏览器,现在普及也还好吧?
完整的Event还有remove、once等方法,可能需要命名空间划分的功能,这些都可以实现的。我就不写了,主要是扯了一下Event模式的封装~
标签:
原文地址:http://www.cnblogs.com/daidaidai/p/5840670.html