分享
 
 
 

用JScript实现VB.Net,C#的[委托Delegate]:

王朝html/css/js·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

用JScript实现VB.Net,C#的[委托Delegate]:

By:

[Lostinet{lostinet@21cn.com;lostinet@chongjian.com}]

[Sun Mar 17 UTC+0800 2002]

VB.Net,C#的委托把对象和方法封装在一个对象内。

今天基于JScript的语法特点,也相应做了类似的功能。

不足之处:

如果Function不是Object的成员,Object必须允许填加新的属性。

例如JScript的对象,DHTML DOM的window,document等;

不行例如有new ActiveXObject("Microsoft.XMLDOM")

如果Function不是Object的成员,在Function调用的时候,必须为Object填加一个

var theIndex="delegate function "+new Date()+" "+Math.random();

=> Object[theIndex]=Function

所以在for(var i in Object)的结构中,theIndex也会出现。

注意事项:

一旦delegate被引用,那么相关的object,function就不会被释放。

要完全释放object,function,必须先释放相关的delegate

脚本和解释如下:

//返回FunctionSelf的调用者,任何函数调用FunctionSelf将返回该函数本身

function FunctionSelf(){return FunctionSelf.caller}

/*

返回封装了obj,func的delegate

例如已知对象和函数:obj1.func1

那么调用obj1.func1(1,2,3)

和调用Delegate(obj1,obj1.func1)(1,2,3)

将会是相似的(除了上面提及的不足之处)

除了这个函数是公开的,其他函数不应该擅自调用。

obj :指定对象

funcOrIndex :指定函数的引用,或者是属于obj的一个名字

*/

function Delegate(obj,funcOrIndex)

{

var delegate=new Function("","FunctionSelf().Call(FunctionSelf().arguments)");

delegate.Object=obj;

delegate.Call=Delegate.Call;

if(typeof(funcOrIndex)=="string")

{

delegate.Index=funcOrIndex;

delegate.Function=obj[funcOrIndex];

}

else

{

delegate.Index=null;

delegate.Function=funcOrIndex;

}

if(typeof(delegate.Function)!="function")throw("没有指定函数!");

return delegate;

}

//当delegate被调用时,这个函数就会被调用。

function Delegate.Call(arguments)

{

/*

涉及到function.arguments允许动态的个数,所以选择了eval来执行。

当一个delegate被调用时,有全局的变量代表了当前被封装的Object,Function,Arguments的集合,

以便被eval调用

*/

//压入当前的delegate的情况

Delegate.Stack.Push(this,arguments);

var strArguments="";

for(var i=0;i<arguments.length;i++)

{

strArguments+="Delegate.Stack().Arguments["+i+"]";

if(i<arguments.length-1)strArguments+=",";

}

if(this.Index)

var theIndex=this.Index;

else

{

var theIndex="delegate function "+new Date()+" "+Math.random();

this.Object[theIndex]=this.Function;

}

var strEval="Delegate.Stack().Delegate.Object[\""+theIndex+"\"]("+strArguments+");";

try//运行delegate,释放当前的delegate的情况

{

eval(strEval);

}

catch(x)

{

//exception的发生可以返回。

//当delegate被嵌套调用时,

//如果中途没有被处理。那么就会返回到最外层

if(!this.Index)delete this.Object[theIndex];

Delegate.Stack.Pop(this);

throw(x);

}

if(!this.Index)delete this.Object[theIndex];//如果是自定义的Index,那么就要删除

Delegate.Stack.Pop();

}

//新建一个全局使用的变量

function Delegate.StackObject(delegate,arguments)

{

this.Delegate=delegate;

this.Arguments=arguments;

}

//返回堆栈当前的对象

function Delegate.Stack()

{

return Delegate.Stack.Object;

}

//Stack的数据

function Delegate.Stack.Array(){}

//因为调用是堆栈形式的,所以数据也是堆栈的。

//压入当前delegate调用的状态。

function Delegate.Stack.Push(delegate,arguments)

{

if(typeof(Delegate.Stack.Position)=="undefined")Delegate.Stack.Position=-1;

Delegate.Stack.Position++;

Delegate.Stack.Object=new Delegate.StackObject(delegate,arguments);

Delegate.Stack.Array[Delegate.Stack.Position]=Delegate.Stack.Object;

}

//Release

function Delegate.Stack.Pop()

{

Delegate.Stack.Array[Delegate.Stack.Position]=null;

Delegate.Stack.Position--;

}

//下面、是例子:

function myalert(str)

{

try{WScript.Echo(str)}catch(x){}

try{alert(str)}catch(x){}

}

var obj=new Object();

obj.value="the obj.value :)";

function func(a,b,c)

{

var str="";

var count=0;

for(var i in this)

{

count++;

str+=i+":"+typeof(this[i])+"\n";

}

var str="a,b,c="+a+":"+b+":"+c+"\nthis.value="+this.value+"\n"+count+"\n"+str;

myalert(str);

}

var delegate=Delegate(obj,func);//传递函数引用

delegate(3,33,333);

obj.callthefunc=func;//或者是:obj["callthefunc"]=func;

delegate=Delegate(obj,"callthefunc");//传递名字

delegate(4,5,6);

var xml=new ActiveXObject("Microsoft.XMLDOM");

var xmlo=new Object();

xmlo.xml=xml;

xmlo.name="xmlo";

xml.onreadystatechange=Delegate(xmlo,onreadystatechange);

xml.load("test1.xml");

var xml2=new ActiveXObject("Microsoft.XMLDOM");

var xmlo2=new Object();

xmlo2.xml=xml2;

xmlo2.name="xmlo2";

xml2.onreadystatechange=Delegate(xmlo2,onreadystatechange);

xml2.load("test2.xml");

function onreadystatechange()

{

if(this.xml.readyState!=4)return;//not ready

if(this.xml.parseError.errorCode)

myalert(this.name+this.xml.parseError.reason);

else

myalert(this.xml.xml);

}

---------------2002.3.8:-------------

function FunctionSelf(){return FunctionSelf.caller;}

function Delegate(obj,funcOrName)

{

var delegate=new Function("","return FunctionSelf().Invoke(FunctionSelf().arguments)");

delegate.Arguments=new Array();

delegate.Object=obj;

delegate.UniqueName="DelegateUniqueID"+Math.floor((new Date().getTime()+Math.random())*1000);

if(typeof(funcOrName)=="string")

{

delegate.FuncName=funcOrName;

delegate.Function=obj[delegate.FuncName];

}

else

{

delegate.FuncName=null;

delegate.Function=funcOrName;

}

delegate.Invoke=Delegate.Invoke;

delegate.Detach=Delegate.Detach;

delegate.SetArguments=Delegate.SetArguments;

delegate.PreInvoke=Delegate.PreInvoke;

delegate.valueOf=new Function("","return \""+delegate.UniqueName+"\"");

delegate.toString=new Function("","return \""+delegate.UniqueName+"\"");

return delegate;

}

function Delegate.GetCaller()

{

var cid=FunctionSelf().caller.caller.CallID;

return Delegate.Coll[cid];

}

function Delegate.GetDelegate()

{

var cid=FunctionSelf().caller.caller.CallID;

return Delegate.Coll[cid].Delegate;

}

function Delegate.PreInvoke()

{

this.SetArguments(Delegate.PreInvoke.arguments);

return this;

}

function Delegate.SetArguments(args)

{

if(args==null)args=new Array();

this.Arguments=new Array();

for(var i=0;i<args.length;i++)this.Arguments[i]=args[i];

return this;

}

function Delegate.Invoke(args)

{

if(this.Object==null)return;

var cid=Delegate.Coll.Insert(this,args);

var strArguments="";

var i=0;

for(i=0;i<args.length;i++)

{

strArguments+="Delegate.Coll['"+cid+"'].Arguments["+i+"]";

if(i<args.length-1)strArguments+=",";

}

if(i>0&&i<this.Arguments.length)strArguments+=",";

for(;i<this.Arguments.length;i++)

{

strArguments+="Delegate.Coll['"+cid+"'].Delegate.Arguments["+i+"]";

if(i<this.Arguments.length-1)strArguments+=",";

}

var funcName=this.FuncName||cid;

if(this.FuncName==null)this.Object[funcName]=this.Function;

var res;

var exception;

try

{

res=eval("new Function('',\"FunctionSelf().CallID='"+cid+"';return Delegate.Coll['"+cid+"'].Delegate.Object['"+funcName+"']("+strArguments+")\")()");

}catch(x){exception=x}

if(this.Object&&(this.FuncName==null))delete this.Object[funcName];

Delegate.Coll.Remove(cid);

if(exception)throw(exception);

return res;

}

function Delegate.Detach()

{

this.Object=null;

this.Function=null;

this.FuncName=null;

this.UniqueName=null;

}

function Delegate.EvalCaller(delegate,args,cid)

{

this.Delegate=delegate;

this.Arguments=args;

this.CallID=cid;

}

function Delegate.Coll(){}

function Delegate.Coll.Insert(delegate,args)

{

if(typeof(Delegate.Coll.Length)=="undefined")Delegate.Coll.Length=0;

Delegate.Coll.Length++;

var cid=delegate.UniqueName+"call"+Math.floor((new Date().getTime()+Math.random())*1000);

var EvalCaller=new Delegate.EvalCaller(delegate,args,cid);

Delegate.Coll[cid]=EvalCaller;

return cid;

}

function Delegate.Coll.Remove(cid)

{

delete Delegate.Coll[cid];

Delegate.Coll.Length--;

}

--------------------例子:

function myjoin()

{

var str="";

for(var i=0;i<myjoin.arguments.length;i++)

str+=myjoin.arguments[i];

return str;

}

alert(

Delegate(new Object(),myjoin)

.PreInvoke(1,2,3,4,5,6,7,8,9)

.PreInvoke("a","b","c","d","e")

(9,8,7,6)

);

---------------

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有