nodejs有eventEmitter 类,想到backbone 有个event模块 可以对对象做事件绑定和触发,是backbone的核心模块。
backbone event模块
- on 添加自定义事件
- off 删除自定义事件
- trigger 派发自定义事件
- once 添加只执行一次的自定义事件 (内部依赖于_.once)
- listenTo 添加一个观察对象
- listenToOnce 添加一个仅执行一次的观察对象
- stopListening 删除添加的观察对象
------------------------------------
on:绑定事件的方法
1 2 3 4 5 6 7 | on: function (name, callback, context) { if (!eventsApi( this , 'on' , name, [callback, context]) || !callback) return this ; this ._events || ( this ._events = {}); var events = this ._events[name] || ( this ._events[name] = []); events.push({callback: callback, context: context, ctx: context || this }); return this ; }, |
在当前的bancbone.event 的实例上添加_events 属性,所有通过backbone.events 订阅的事假, 都在这个哈希表上。
_events 的结构,先哈希后数组,其中 ctx, context赋值回调函数的this
1 2 3 4 | _events={ eventName:[handlerObj,handlerObj,handlerObj], eventName:[{callback: function (){}, context: Object, ctx: Object}] } |
trigger:
1 2 3 4 5 6 7 8 9 10 | trigger: function (name) { if (! this ._events) return this ; var args = slice.call(arguments, 1); /*获得传入callback的参数类型数组 */ if (!eventsApi( this , 'trigger' , name, args)) return this ; var events = this ._events[name]; var allEvents = this ._events.all; if (events) triggerEvents(events, args); //triggerEvents 针对 apply call做了性能优化 if (allEvents) triggerEvents(allEvents, arguments); //如果 当前实例有事件名为all的事件,在触发完指定的name事件后还会触发all的事件 return this ; } |
triggerEvents :执行_events[name]中的方法
官方解释因为call的性能比apply好 ,所以三个参数以下都使用call,三个参数以上才使用apply,大神的要求就是这么高
1 2 3 4 5 6 7 8 9 10 | var triggerEvents = function (events, args) { var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; switch (args.length) { case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return ; case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return ; case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return ; case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return ; default : while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return ; } }; |