JQuery源码解析(十)
JQuery源码解析(十)
默认回调对象设计
不传入任何参数,调用add的时候将函数add到内部的list中,调用fire的时候顺序触发list中的回调函数:
function fn1(val) { console.log('fn1 says:' + val);}function fn2(val) { console.log('fn2 says ' + val);}var cbs = $.Callbacks();cbs.add(fn1);cbs.fire('foo');console.log('........')cbs.add(fn2);cbs.fire('bar')
结果就是按照顺序叠加触发,如下列表:
fn1 says:foo ………………………fn1 says:bar fn2 says bar
这种就是最简单的处理了,可以直接模拟,代码如下:
function Callbacks() { var list = []; var self; self = { add: function(fn) { list.push(fn) }, fire: function(args) { list.forEach(function(fn) { fn(args); }) } } return self;}
代码:
unique的设计
Unique:确保一次只能添加一个回调(所以在列表中没有重复的回调)
function fn1(val) { console.log('fn1 says ' + val);}var callbacks = $.Callbacks( "unique" );callbacks.add( fn1 );callbacks.add( fn1 ); // repeat additioncallbacks.add( fn1 );callbacks.fire( "foo" );
结果:过滤了相同的add操作
fn1 says foo
过滤重复的比较简单,因为是数组的保存方式,我们可以在入口处通过indexOf判断即可
function Callbacks(options) { var list = []; var self; var firingStart; var memory; function _fire(data) { memory = options === 'memory' && data; firingIndex = firingStart || 0; firingStart = 0; firingLength = list.length; for (; list && firingIndex < firingLength; firingIndex++) { list[firingIndex](data) } } self = { add: function(fn) { var start = list.length; if (options == 'unique') { if (-1 === list.indexOf(fn)) { list.push(fn) } } else { list.push(fn) } if (memory) { firingStart = start; //获取最后一值 _fire(memory); } }, fire: function(args) { if (list) { _fire(args) } } } return self;}
实例代码: