In my previous blog 《Extension Function (1): Extend》 already extension "Function" function to implement Extend.

follow the lead i'll talk about extension "Function" to implement Multicast Event.


Some friends may familiar with listener model,Some friends may be not.

But event I believe these is no one none used.

In Js,We usually use blew code to implement event.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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()

It's easy and effective when just only one function to regist.

But if we need regist multicast event as we used in c#.

what can we do?

As usual,here is the core code.

//event regist function
//@param eventName:regist event name
//@param func:to regist function
//@param executor:execute context,if null then use default context.
Function.prototype.AddEventListener =
function (eventName, func, executor) {
    //key method to execute multicast event
    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);
}
//Remove Event Regist function
//@param eventName:event name
//@param funcHandle:to remove function object,if not use origin //function object which use to regist then there is no effect.
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);
        }
    }
}


use already defined class

and here is the demo.


var c=new eventDemoClass();
var listener=function(){alert("staff was done")}
c.AddEventListener("OnDoSomeStaff",listener,c);
c.DoSomeStaff();//will alert
c.RemoveEventListener("OnDoSomeStaff",listener);
c.DoSomeStaff();//will not alert


then multicast event is implemented.