当前位置:首页 > 开发 > Web前端 > Ajax > 正文

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

发表于: 2006-12-27   作者:cleverpig   来源:转载   浏览次数:
摘要: Prototype.AjaxRequest的调用堆栈重写问题<o:p></o:p> 作者:cleverpig<o:p></o:p> <o:p> </o:p> 由于调用AjaxRequest类进行XMLHTTPRequest操作时,this引用(指向当前function所在的对象)会出现了call stack问题

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开发手册

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
位置: 调试 >> 窗口 >> 调用堆栈 说明: 任何一个项目都会对项目进行各种层次和模块的
作者 xgywinner 日期 2009-3-18 11:44:00 1) 在栈上创建。在执行函数时,函数内局部变量的存储单元
函数调用约定和堆栈 1 什么是堆栈 编译器一般使用堆栈实现函数调用。堆栈是存储器的一个区域,嵌入
1 // fun.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx
调试小技巧---利用调用堆栈 如图:在解决bug的时候,不能确定下一步程序执行到哪,可以利用Xcode
最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--重写修改 点击listview的行有时表
7 堆栈
一.、JAVA中的数据存储 在JAVA中,有六个不同的地方可以存储数据:寄存器、栈、堆、静态存储、常量
公司的手游项目,使用的是基于cocos2d-x绑lua的解决方案(参数quick-x的绑定),虽然使用了lua进行
from:http://stackoverflow.com/questions/2515598/push-ebp-movlesp-ebp 大家在通过反汇编去分析g
堆栈 目录 什么是堆栈 堆和栈的区别 堆和栈的理论知识 堆和栈的区别主要分: 补充 [ 编辑本段] 什么
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号