在我的上一篇博文《Function的扩展(1):继承》中已经对扩展function这个函数以实现继承。
按照写文章的顺杆爬理论我就在这一篇和大家聊一下通过对Function的扩展实现多播事件吧。。
对于监听者模式有些朋友可能很熟悉,也有些朋友可能不太了解。但是对于事件。相信几乎没有人没用过吧。。
在Js中,我们往往是采用类似以下代码的方式来进行事件的编写与调用。
var eventDemoClass= function () { //constructor } eventDemoClass.prototype = (function () { //private return { //public OnDoSomeStaff:null, DoSomeStaff:function(){ // some function code if(this.OnDoSomeStaff){ this.OnDoSomeStaff(object,args); } } }; })(); var c=new eventDemoClass(); c.OnDoSomeStaff=function(){ alert("staff was done"); } c.DoSomeStaff()
这样写很简单同时在只会有一个方法进行注册的时候也很有效。
但是如果我们需要像c#的事件一样注册多播事件又该怎么办呢?
老规矩。核心代码呈上。
//注册事件方法 //@param eventName:事件名 //@param func:进行注册的方法 //@param executor:执行上下文对象 如果为空则使用默认上下文 Function.prototype.AddEventListener = function (eventName, func, executor) { var eventFunc = function () {//多播事件执行关键方法 var eventArray = arguments.callee.FunctionArray; var executorArray = arguments.callee.Executor; for (var i = 0; i < eventArray.length; i++) { var executor = executorArray[i]; if (!executor) { executor = this; } eventArray[i].apply(executor, arguments); } } if (!this[eventName] || !this[eventName].FunctionArray) { this[eventName] = eventFunc; this[eventName].FunctionArray = []; this[eventName].Executor = []; } this[eventName].FunctionArray.push(func); this[eventName].Executor.push(executor); } //取消注册方法 //@param eventName:事件名 //@param funcHandle:取消注册的方法对象 如果不是注册时使用的原对象, //将无法进行取消动作 Function.prototype.RemoveEventListener = function (eventName, funcHandle) { if (this[eventName] && this[eventName].FunctionArray) { var index = this[eventName].FunctionArray.RemoveObject(funcHandle); if (index >= 0) { this[eventName].Executor.RemoveIndex(index); } } }
还是使用刚才定义的eventDemo类。
调用代码如下
var c=new eventDemoClass(); var listener=function(){alert("staff was done")} c.AddEventListener("OnDoSomeStaff",listener,c); c.DoSomeStaff();//将会弹出窗体 c.RemoveEventListener("OnDoSomeStaff",listener); c.DoSomeStaff();//将不会弹出窗体
这样多播事件就实现了。