Prototype.AjaxRequest的调用堆栈重写问题

由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题,从而指向当前的对象:
错误演示:
var OverWritingDemonstrate=Class.create();
OverWritingDemonstrate. prototype ={
    xml_source: '' ,
    initialize: function (){
    },
    putRequest: function (url,params,callBackFunction){
       var funcHolder= arguments . callee .$;
        var xmlHttp = new Ajax.Request(url,
           {
              method: 'get' ,
                   parameters: params,
              requestHeaders:[ 'my-header-encoding' , 'utf-8' ],
                   onFailure: function (){
                  alert ( ' 对不起,网络通讯失败,请重新刷新! ' );
              },
              onSuccess: function (transport){
              },
              onComplete: function (transport){
                  this.xml_source=transport.responseText;
                  this.showXMLResponse();
              }
           });
    },
    // 显示 xml 信息
    showXMLResponse: function (){
       alert (this.xml_source);
    },
    …
}
这样使用必定找不到 showXMLResponse 方法,因为在 AjaxRequest onComplete 函数中的 this 指向了当前的 function 所在的对象 xmlHttp ,而不是我们的 OverWritingDemonstrate 类对象。
 
Fix方法:
我们可以借鉴一下《解开JavaScript生命的达芬奇密码》Joshua Gertzen的方法,实现一个ClassUtils类:
// 类工具
var ClassUtils=Class.create();
ClassUtils. prototype ={
    _ClassUtilsName: 'ClassUtils' ,
    initialize: function (){
    },
    /**
      * 给类的每个方法注册一个对类对象的自我引用
      * @param reference 对类对象的引用
      */
    registerFuncSelfLink: function (reference){
       for ( var n in reference) {
        var item = reference[n];                       
        if (item instanceof Function )
              item.$ = reference;
    }
    }
}
 
然后修改一下前面的 OverWritingDemonstrate ,这里为了达到区分效果的目的,类名取为 AjaxWrapper
//Ajax 操作封装类:
// 由于调用 AjaxRequest 类进行 XMLHTTPRequest 操作时, this 引用(指向当前的对象)会出现了 call stack 问题,从而指向当前的对象。
// 所以,对 putRequest callBackHandler 、以及 callback 方法都要使用 arguments.callee.$ 来获得正确的类对象引用
var AjaxWrapper=Class.create();
AjaxWrapper. prototype ={
    xml_source: '' ,
    /**
      * 初始化
      * @param isDebug 是否显示调试信息
      */
    initialize: function (isDebug){
       new ClassUtils().registerFuncSelfLink( this );
    },
    putRequest: function (url,params,callBackFunction){
       var funcHolder= arguments . callee .$;
        var xmlHttp = new Ajax.Request(url,
           {
              method: 'get' ,
                parameters: params,
              requestHeaders:[ 'my-header-encoding' , 'utf-8' ],
                onFailure: function (){
                  alert ( ' 对不起,网络通讯失败,请重新刷新! ' );
              },
              onSuccess: function (transport){
              },
              onComplete: function (transport){
                  funcHolder .xml_source=transport.responseText;
                  funcHolder .showXMLResponse();
              }
           });
    },
    // 显示 xml 信息
    showXMLResponse: function (){
       alert ( funcHolder .xml_source);
    },
    …
}
这样就避免了发生在调用堆栈中的this重写问题了。
 

你可能感兴趣的:(Prototype.AjaxRequest的调用堆栈重写问题)