[转]做ajax请求时callback函数调用时this变量的变化问题 ---- 转自: http://www.iteye.com/problems/78800
码大致如下
- var a = (function(){
- var a = function (...,param) {
- return new a.fn.init (...,param)
- }
- a.fn = a.prototype = {
- init: function (...) {
- ...
- this.param = param
- }
- callback: function (response) {
- this.param //这里似乎this发生改变,this.param值为undefined
- ...
- }
- getData: function() {
- //通过ajax获得数据,然后回调 callback
- doGetAjax(url,data,this.callback)
- }
- }
- a.fn.init.prototype = a.fn;
- })()
像这种地方想要在callback获得param应该怎么做?
edit1
--------------------------------------
想了一下,这里ajax返回调用的时候this已经没有绑定了,在a内找不到再次与this绑定的方法,
那就不使用this,使用函数类的局部全局变量达到私有变量的效果,
代码改变如下
:
- var a = (function(){
- var pParam; //添加私有变量
- ...
- init: function (...) {
- ...
- pParam=this.param = param
- }
- ...
- callback: function (response) {
- pParam //这里似乎this发生改变,this.param值为undefined
- ...
- }
想了一下,是否所有对象的属性都应该赋值给 私有变量,而 this.XXX则是要暴露给外界才多加一个赋值?
edit 2
-------------------------
这两天重新看了下,发现这种私有变量是所有实例共享的,一个页面有多个同类组件的话就不行了.
如果是存储一个共享私有变量,每次ajax请求以后都手动立刻将私有变量赋值给相应实例变量,但这样的缺点是多次自动进行ajax操作的话是实现不了的,比如分页ajax请求。
这种情况究竟咋解决.
问题补充:
yaolifei 写道
感觉你说的很乱,猜的也很乱,这是一个基本的问题。
假设你的代码是这样的:
执行到doGetAjax这里时,调用doGetAjax的是谁?这个你一定要搞清楚。
你不妨在doGetAjax方法中加上alert(this)看看:
可以看出doGetAjax这个方法是全局的,也可以说是window的对象,那么调用这个
方法的就是window,所以alert(this)打出来的也是: Object DOMWindow这个对象
然后你执行cb()这个时候还是用window对象去执行cb,所以你回调方法:
这个里面的this应是window对象,当然获取不到param,如果你想获得obj的param的话应该这样:
调用的时候要把当前对象指针传过去:
这样this才是obj而不是window了。
假设你的代码是这样的:
- <script type="text/javascript">
- doGetAjax = function(url, data, cb){
- //....
- var response = {};
- cb(response);
- }
- var a = function(){
- }
- a.prototype = {
- init: function(param){
- this.param = param;
- },
- callback: function(response){
- alert(this.param);
- },
- getData: function(){
- //通过ajax获得数据,然后回调 callback
- var url = '', data = {};
- doGetAjax(url,data,this.callback)
- }
- }
- var obj = new a();
- obj.init('a');
- obj.getData();
- </script>
执行到doGetAjax这里时,调用doGetAjax的是谁?这个你一定要搞清楚。
你不妨在doGetAjax方法中加上alert(this)看看:
- doGetAjax = function(url, data, cb){
- //....
- alert(this);
- cb();
- }
可以看出doGetAjax这个方法是全局的,也可以说是window的对象,那么调用这个
方法的就是window,所以alert(this)打出来的也是: Object DOMWindow这个对象
然后你执行cb()这个时候还是用window对象去执行cb,所以你回调方法:
- callback: function(response){
- alert(this.param);
- },
这个里面的this应是window对象,当然获取不到param,如果你想获得obj的param的话应该这样:
- doGetAjax = function(url, data, cb, scope){
- //....
- var response = {};
- cb.call(scope, response);
- }
调用的时候要把当前对象指针传过去:
- getData: function(){
- //通过ajax获得数据,然后回调 callback
- var url = '', data = {};
- doGetAjax(url,data,this.callback, this)
- }
这样this才是obj而不是window了。
是知道那里调用是window对象的,只是不知道如何在doGetAjax后仍将this绑定到现在这个对象上,当时想的是存到 私有共享变量里,然后在回调中绑定,不过这样一个页面就不能由两个相同类型的对象了,不然会出问题.
你的答案是调用ajax方法时把当前对象当做参数传进去.明白了.
谢谢
谢谢.