比较常见的一种机制是,定义一个Util对象,再定义它的add,remove,call方法,示例如下:
window.Util = { _fns : [], add : function (fn){ return this._fns.push(fn); }, remove : function (index){ delete this._fns.push(index-1); }, invoke : function (index){ return this._fns[index].apply(window, Array.prototype.slice.call(arguments,1)); } }; // 注册 var fnId = Util.add( function( msg ) { alert( msg ); } ); // 调用 Util.invoke(fnId, 'Hello, World' ); //-> 'Hello, World'; // 销毁 Util.remove(fnId);这种方法虽然也不复杂,但是我觉得还是不够简练。CKEditor里用的方式是写在闭包里,把_fns藏起来了,但使用方式还是差不多,要Util.addFunction(), Util.removeFunction(), Util.callFunction()。
我写了一个更简练的,直接用Util()来调用。代码如下:
//把Util在闭包里进行定义 ( function() { var fns = [],ta; window.Util = function (a){ ta=typeof a; if(ta==='number'){ if(a>0){ if(fns[a-1]){ return fns[a-1].apply(window, Array.prototype.slice.call(arguments,1)); } }else{ delete fns[-a-1]; } }else if(ta==='function'){ return fns.push(a); } }; }()); // 注册 var fnId = Util( function( msg ) { alert( msg ); } ); // 调用 Util( fnId, 'Hello, World' ); //-> 'Hello, World'; // 销毁,在id前面加上负号,既省事,也有语义 Util( - fnId); // 销毁后调用,无效果 Util( fnId, 'Hello, World' );
通过这样的机制,最大程度简化了注册-调用-销毁的使用。
记得jQuery的万能$不?思路是一致的,我们要:写的更少,做的更多。