Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

[转]做ajax请求时callback函数调用时this变量的变化问题 ---- 转自: http://www.iteye.com/problems/78800

码大致如下 

Javascript代码  收藏代码
  1. var a = (function(){  
  2.   var  a = function (...,param) {  
  3.     return new a.fn.init (...,param)    
  4.   }  
  5.   a.fn = a.prototype = {  
  6.     init: function (...) {  
  7.       ...  
  8.       this.param = param  
  9.     }  
  10.     callback: function (response) {  
  11.       this.param //这里似乎this发生改变,this.param值为undefined  
  12.       ...  
  13.     }  
  14.     getData: function() {  
  15.       //通过ajax获得数据,然后回调 callback  
  16.       doGetAjax(url,data,this.callback)  
  17.     }  
  18.   }  
  19.   a.fn.init.prototype = a.fn;  
  20. })()  


像这种地方想要在callback获得param应该怎么做? 

edit1 
-------------------------------------- 
想了一下,这里ajax返回调用的时候this已经没有绑定了,在a内找不到再次与this绑定的方法, 
那就不使用this,使用函数类的局部全局变量达到私有变量的效果, 
代码改变如下 

Javascript代码  收藏代码
  1. var a = (function(){  
  2.   var pParam; //添加私有变量  
  3.   ...  
  4.   init: function (...) {  
  5.     ...  
  6.     pParam=this.param = param  
  7.   }  
  8.   ...  
  9.   callback: function (response) {  
  10.     pParam //这里似乎this发生改变,this.param值为undefined  
  11.     ...  
  12.   }  


想了一下,是否所有对象的属性都应该赋值给 私有变量,而 this.XXX则是要暴露给外界才多加一个赋值? 

edit 2 
------------------------- 
这两天重新看了下,发现这种私有变量是所有实例共享的,一个页面有多个同类组件的话就不行了. 
如果是存储一个共享私有变量,每次ajax请求以后都手动立刻将私有变量赋值给相应实例变量,但这样的缺点是多次自动进行ajax操作的话是实现不了的,比如分页ajax请求。 

这种情况究竟咋解决.


问题补充:
yaolifei 写道
感觉你说的很乱,猜的也很乱,这是一个基本的问题。 
假设你的代码是这样的: 
Js代码  收藏代码
  1. <script type="text/javascript">  
  2.     doGetAjax = function(url, data, cb){  
  3.         //....  
  4.         var response = {};  
  5.         cb(response);  
  6.     }  
  7.       
  8.     var a = function(){  
  9.     }  
  10.       
  11.     a.prototype = {  
  12.         init: function(param){  
  13.             this.param = param;  
  14.         },  
  15.         callback: function(response){  
  16.             alert(this.param);  
  17.         },  
  18.         getData: function(){  
  19.           //通过ajax获得数据,然后回调 callback  
  20.           var url = '', data = {};  
  21.           doGetAjax(url,data,this.callback)  
  22.         }     
  23.     }  
  24.       
  25.     var obj = new a();  
  26.     obj.init('a');  
  27.     obj.getData();  
  28. </script>   

执行到doGetAjax这里时,调用doGetAjax的是谁?这个你一定要搞清楚。 
你不妨在doGetAjax方法中加上alert(this)看看: 
Js代码  收藏代码
  1. doGetAjax = function(url, data, cb){  
  2.     //....  
  3.     alert(this);  
  4.     cb();  
  5. }  

可以看出doGetAjax这个方法是全局的,也可以说是window的对象,那么调用这个 
方法的就是window,所以alert(this)打出来的也是: Object DOMWindow这个对象 
然后你执行cb()这个时候还是用window对象去执行cb,所以你回调方法: 
Js代码  收藏代码
  1. callback: function(response){  
  2.     alert(this.param);  
  3. },  

这个里面的this应是window对象,当然获取不到param,如果你想获得obj的param的话应该这样: 
Js代码  收藏代码
  1. doGetAjax = function(url, data, cb, scope){  
  2.     //....  
  3.     var response = {};  
  4.     cb.call(scope, response);  
  5. }  

调用的时候要把当前对象指针传过去: 
Js代码  收藏代码
  1. getData: function(){  
  2.     //通过ajax获得数据,然后回调 callback  
  3.     var url = '', data = {};  
  4.     doGetAjax(url,data,this.callback, this)  
  5. }     

这样this才是obj而不是window了。

是知道那里调用是window对象的,只是不知道如何在doGetAjax后仍将this绑定到现在这个对象上,当时想的是存到 私有共享变量里,然后在回调中绑定,不过这样一个页面就不能由两个相同类型的对象了,不然会出问题. 

你的答案是调用ajax方法时把当前对象当做参数传进去.明白了. 
谢谢 
谢谢.

posted on 2013-12-20 15:48  RJ  阅读(288)  评论(0)    收藏  举报

导航