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方法,因为在AjaxRequest的onComplete函数中的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> //所以,对putRequest、callBackHandler、以及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>
相关推荐
NULL 博文链接:https://chun521521.iteye.com/blog/1935516
NULL 博文链接:https://linwei-211.iteye.com/blog/1567277
ajax.js是本人从prototype-1.3.1.js提取的ajax库 为方便调用,本人另写了两个函式:mmAjaxUpdater和mmAjaxRequest,在实践中,这两个函数只兼容prototype1.3.1版本。因此对以上函数进行重写,现在已兼容所有版本的...
Ext.Ajax.request同步请求包 博文链接:https://lingf.iteye.com/blog/1195912
1.4.1. 使用 Ajax.Request类 1.4.2. 使用 Ajax.Updater 类 2. prototype.js参考 2.1. JavaScript 类的扩展 2.2. 对 Object 类的扩展 2.3. 对 Number 类的扩展 2.4. 对 Function 类的扩展 2.5. 对 String 类的扩展 ...
prototype.js是一个非常优雅的javascript基础类库,对javascript做了大量的扩展,而且很好的支持Ajax,国外有多个基于此类库实现的效果库,也做得很棒。 prototype.js不仅是一个有很大实用价值的js库,而且有很...
AJAX类prototype.js,AJAX类prototype.js,AJAX类prototype.js,AJAX类prototype.js
prototype 框架实现ajax实例
prototype.js的系列文章——$H()函数 百度的Ajax.js文件 常用JS ...prototype.js的系列文章——Ajax.Request类 prototype.js的系列文章——Ajax.Updater类 prototype.js的系列文章——Try.these())函数
Ext Ajax:如何调用Ext.Ajax.request方法和使用Java Servlet进行处理
使用$.Ajax调用后台.aspx
主要介绍了ExtJs的Ext.Ajax.request实现waitMsg等待提示效果,需要的朋友可以参考下
prototype.js是一个非常优雅的javas cript基础类库,对javas cript做了大量的扩展,而且很好的支持Ajax,国外有多个基于此类库实现的效果库,也做得很棒。 prototype.js不仅是一个有很大实用价值的js库,而且有很高...
NULL 博文链接:https://lingf.iteye.com/blog/1821225
the manual of prototype 博文链接:https://spamer.iteye.com/blog/176156
封装jquery ajax方法,方便调用,避免在代码中频繁使用 $.ajax({ type: 'GET', url: url, ...... )}; 统一调用公共方法即可,区分同步异步,get post!希望对大家有帮助
经典ajax.prototype.javascript实例
ajax.prototype.javascript实例打包下载
prototype.js ajax,javascript框架学习