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

阅读更多

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

作者:cleverpig

 

由于调用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方法,因为在AjaxRequestonComplete函数中的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问题,从而指向当前的对象。

//所以,对putRequestcallBackHandler、以及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重写问题了。

 

代码下载:

    demonstrate.rar

相关资源:

   解开JavaScript生命的达芬奇密码

   Prototype JavaScript framework website

   Prototype 快速教学

   Prototype开发手册

你可能感兴趣的:(prototype,Ajax,XML,JavaScript,编程)