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>
相关推荐
标题"Ext.Ajax.request跨域"指出我们将探讨如何使用ExtJS库中的Ajax模块进行跨域请求。Ext.Ajax.request是ExtJS提供的一种发起Ajax请求的方式,它允许开发者向服务器发送异步HTTP请求。然而,由于浏览器的同源策略...
在EXTJS库中,`Ext.Ajax.request`是用于发送Ajax请求的核心方法,它支持异步和同步操作。本文将详细解析如何利用`Ext.Ajax.request`实现同步请求,并探讨其背后的原理和注意事项。 首先,我们需要理解Ajax的本质,...
这篇文章将深入探讨`Ext.Ajax.request`的使用,以及在实际应用中可能遇到的小问题。 首先,`Ext.Ajax.request`的基本语法如下: ```javascript Ext.Ajax.request({ url: 'your-url', method: 'GET', // 可选值有...
3. **Ajax** - prototype.js 改进了原始的XMLHttpRequest对象,提供了`Ajax`模块,包含`Ajax.Request`和`Ajax.Updater`等类,使异步数据交换更加简单和灵活。 4. **事件处理** - 库中的`Event.observe()`和`Event....
2. **Ajax**:Prototype.js提供了一套完善的Ajax解决方案,包括`Ajax.Request`和`Ajax.Updater`,使得异步数据交互更为简单,同时支持JSON、XML等多种数据格式。 3. **事件处理**:Prototype.js通过`Event.observe...
- **Ajax支持**:`prototype.js`提供了一套完整的Ajax解决方案,包括`Ajax.Request`、`Ajax.Updater`和`Ajax.PeriodicalUpdater`等类,使得异步通信更为简便。 - **事件处理**:它增强了事件处理机制,允许绑定和...
2. **Ajax功能**:Prototype.js 强化了AJAX操作,通过`Ajax.Request` 和 `Ajax.Updater` 类,开发者可以轻松实现异步数据交换,无需关心浏览器兼容性问题。 3. **对象扩展**:Prototype.js 基于JavaScript原型链...
`Ajax.Request`和`Ajax.Updater`是核心组件,前者用于发送请求,后者用于更新页面的一部分。它们都支持多种HTTP方法(GET、POST等),并能处理JSON、XML等多种数据格式。 ### 4. 动画效果 Prototype.js 提供了强大...
Prototype.js 提供了强大的Ajax功能,包括`Ajax.Request`和`Ajax.Updater`等,它们简化了异步请求和页面局部更新的代码。通过这些工具,开发者可以轻松构建富交互性的Web应用。 6. **动画效果** 库中还包含了一些...
`Ajax.Request`和`Ajax.Updater`是其中两个关键的类,它们分别用于发起完整的HTTP请求和替换页面的部分内容。 Prototype.js的另一个显著特点是对JavaScript对象的增强。1.7.3版本继续沿用了基于类的模拟实现,通过`...
Prototype.js 的 AJAX 支持在 1.6 版本中得到增强,`Ajax.Request` 和 `Ajax.Updater` 类提供了一种优雅的方式来处理异步数据交换。新版本增加了错误处理机制,同时支持 JSONP 和 CORS,适应了跨域请求的需求。 ###...
`Ajax.Request`和`Ajax.Updater`可以轻松发起GET或POST请求,并处理响应。此外,还有`Ajax.PeriodicalUpdater`用于定期更新页面内容。 - **JSON支持**:Prototype.js提供了`toJSON`方法,可以将JavaScript对象转换...
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 类的扩展 ...
3. **Ajax支持**:Prototype.js提供了强大的Ajax功能,包括`Ajax.Request`和`Ajax.Updater`等,它们允许开发者轻松实现页面的异步更新,无需刷新整个页面,从而提高用户体验。 4. **事件处理**:库中包含了事件绑定...
Ajax.Request类用于发送Ajax请求。 1.4.2.使用Ajax.Updater类 Ajax.Updater类用于更新页面中的某个元素。 二、Prototype.js参考 Prototype.js提供了许多有用的函数和方法,以帮助开发者快速构建Web应用程序。...
3. **Ajax支持**:Prototype的`Ajax`模块提供了一套完整的异步数据交互接口,包括`Ajax.Request`和`Ajax.Updater`等。 4. **事件处理**:Prototype简化了事件处理,通过`Event.observe`和`Event.stop`等方法可以...
1. **Ajax.Request**: 这是Prototype的核心AJAX方法,用于发起HTTP请求。例如: ```javascript new Ajax.Request('url', { method: 'get' || 'post', parameters: {key: value}, // 发送的数据 onSuccess: ...
`Ajax.Request`和`Ajax.Updater`类用于发送HTTP请求,处理响应数据,实现了页面局部更新。 2. **Selectors API**:Prototype.js兼容了CSS选择器,提供了`$$()`函数,可以像操作CSS一样选取DOM元素,增强了...
prototype.js是一个非常优雅的javascript基础类库,对javascript做了大量的扩展,而且很好的支持Ajax,国外有多个基于此类库实现的效果库,也做得很棒。 prototype.js不仅是一个有很大实用价值的js库,而且有很...