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

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 lostinet 的 blog

用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");



本文关键:JScript
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top