在我的上一篇博文《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();//將不會彈出窗體
這樣多播事件就實現了。