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

本文介绍了解决Prototype.AjaxRequest中this指向错误的问题,通过创建ClassUtils类并注册函数自我引用,确保了回调函数中正确地访问到了外部类的属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Prototype.AjaxRequest的调用堆栈重写问题<o:p></o:p>

作者:cleverpig<o:p></o:p>

<o:p> </o:p>

由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题,从而指向当前的对象:<o:p></o:p>

错误演示:<o:p></o:p>

var OverWritingDemonstrate=Class.create();<o:p></o:p>

OverWritingDemonstrate.prototype={<o:p></o:p>

    xml_source:'',<o:p></o:p>

    initialize:function(){<o:p></o:p>

    },<o:p></o:p>

    putRequest:function(url,params,callBackFunction){<o:p></o:p>

       var funcHolder=arguments.callee.$;<o:p></o:p>

        var xmlHttp = new Ajax.Request(url,<o:p></o:p>

           {<o:p></o:p>

              method: 'get', <o:p></o:p>

                   parameters: params, <o:p></o:p>

              requestHeaders:['my-header-encoding','utf-8'],<o:p></o:p>

                   onFailure: function(){<o:p></o:p>

                  alert('对不起,网络通讯失败,请重新刷新!');<o:p></o:p>

              },<o:p></o:p>

              onSuccess: function(transport){<o:p></o:p>

              },<o:p></o:p>

              onComplete: function(transport){<o:p></o:p>

                  this.xml_source=transport.responseText;<o:p></o:p>

                  this.showXMLResponse();<o:p></o:p>

              }<o:p></o:p>

           });<o:p></o:p>

    },<o:p></o:p>

    //显示xml信息<o:p></o:p>

    showXMLResponse:function(){<o:p></o:p>

       alert(this.xml_source);<o:p></o:p>

    },<o:p></o:p>

    …<o:p></o:p>

}<o:p></o:p>

这样使用必定找不到showXMLResponse方法,因为在AjaxRequestonComplete函数中的this指向了当前的function所在的对象xmlHttp,而不是我们的OverWritingDemonstrate类对象。<o:p></o:p>

<o:p> </o:p>

Fix方法<o:p></o:p>

我们可以借鉴一下《解开JavaScript生命的达芬奇密码》Joshua Gertzen的方法,实现一个ClassUtils类:<o:p></o:p>

//类工具<o:p></o:p>

var ClassUtils=Class.create();<o:p></o:p>

ClassUtils.prototype={<o:p></o:p>

    _ClassUtilsName:'ClassUtils',<o:p></o:p>

    initialize:function(){<o:p></o:p>

    },<o:p></o:p>

    /**<o:p></o:p>

     * 给类的每个方法注册一个对类对象的自我引用<o:p></o:p>

     * @param reference 对类对象的引用<o:p></o:p>

     */<o:p></o:p>

    registerFuncSelfLink:function(reference){<o:p></o:p>

       for (var n in reference) {<o:p></o:p>

        var item = reference[n];                        <o:p></o:p>

        if (item instanceof Function) <o:p></o:p>

              item.$ = reference;<o:p></o:p>

    }<o:p></o:p>

    }<o:p></o:p>

}<o:p></o:p>

<o:p> </o:p>

然后修改一下前面的OverWritingDemonstrate,这里为了达到区分效果的目的,类名取为AjaxWrapper<o:p></o:p>

//Ajax操作封装类:<o:p></o:p>

//由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前的对象)会出现了call stack问题,从而指向当前的对象。<o:p></o:p>

//所以,对putRequestcallBackHandler、以及callback方法都要使用arguments.callee.$来获得正确的类对象引用<o:p></o:p>

var AjaxWrapper=Class.create();<o:p></o:p>

AjaxWrapper.prototype={<o:p></o:p>

    xml_source:'',<o:p></o:p>

    /**<o:p></o:p>

     * 初始化<o:p></o:p>

     * @param isDebug 是否显示调试信息<o:p></o:p>

     */<o:p></o:p>

    initialize:function(isDebug){<o:p></o:p>

       new ClassUtils().registerFuncSelfLink(this);<o:p></o:p>

    },<o:p></o:p>

    putRequest:function(url,params,callBackFunction){<o:p></o:p>

       var funcHolder=arguments.callee.$;<o:p></o:p>

        var xmlHttp = new Ajax.Request(url,<o:p></o:p>

           {<o:p></o:p>

              method: 'get', <o:p></o:p>

                parameters: params, <o:p></o:p>

              requestHeaders:['my-header-encoding','utf-8'],<o:p></o:p>

                onFailure: function(){<o:p></o:p>

                  alert('对不起,网络通讯失败,请重新刷新!');<o:p></o:p>

              },<o:p></o:p>

              onSuccess: function(transport){<o:p></o:p>

              },<o:p></o:p>

              onComplete: function(transport){<o:p></o:p>

                  funcHolder.xml_source=transport.responseText;<o:p></o:p>

                  funcHolder.showXMLResponse();<o:p></o:p>

              }<o:p></o:p>

           });<o:p></o:p>

    },<o:p></o:p>

    //显示xml信息<o:p></o:p>

    showXMLResponse:function(){<o:p></o:p>

       alert(funcHolder.xml_source);<o:p></o:p>

    },<o:p></o:p>

    …<o:p></o:p>

}<o:p></o:p>

这样就避免了发生在调用堆栈中的this重写问题了。<o:p></o:p>

<o:p> </o:p>

代码下载:

    demonstrate.rar

相关资源:<o:p></o:p>

   解开JavaScript生命的达芬奇密码<o:p></o:p>

   Prototype JavaScript framework website

   Prototype 快速教学

   Prototype开发手册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值