javascript scope的研究

本文探讨了JavaScript中函数调用时this关键字的指向问题。通过具体实例分析,解释了对象方法调用与普通函数调用时this的不同指向,并给出了避免undefined返回值的有效解决方案。

 首先有个原则:

就是在Javascript中,对于scope的处理,如果是被对象调用的函数,比如o.f() 的形式,那么this 指针指向“点”前面的对象,比如这里的o.

如果是普通函数,也就是没有“点”号,那么对于浏览器来说,这个this指针指向的是window.

附上测试源代码:

 


  1. var theAccumulator={ 
  2.                                  
  3.          total:0, 
  4.          clear:function(){ 
  5.                  this.total=0 ; 
  6.                }, 
  7.          add:function(x){ 
  8.                 this.total+=x; 
  9.              }, 
  10.          getResult:function(){ 
  11.               return this.total; 
  12.              } 
  13.                                  
  14. function printResult(f){ 
  15.      alert("result=" + f()); 
  16.                                  
  17. theAccumulator.clear();  
  18. theAccumulator.add(100); 
  19. theAccumulator.add(200);           
  20. printResult(theAccumulator.getResult);   

在这种情况下,为什么是undefined呢?

因为printResult(theAccumulator.getResult) 传递进去的是一个类似C里面函数指针的方式,这个方式是可取的(没有任何语法毛病,我一开始以为是有语法毛病的),因为

 


  1. theAccumulator.getResult  

是代表以下函数体



  1.   
  2.  
  3. function(){ 
  4.  
  5. return this.total; 
  6.  
  7.  } 
  8.  
  9.   
  10.  
  11.   

所以原始写法就等效于printResult(



  1. function(){ 
  2.  
  3. return this.total; 
  4.  
  5.   } 
  6.  
  7. );  
  8.  
  9.   

这里看出,括号内部匿名方法(也就是function(){})没有被任何对象所调用。所以它是“普通方法”,所以他的函数体里面的this指向的是window,而window 这个scope上并没有一个叫total的成员(因为total成员是theAccumulator的,而不是window的),所以会出现undefined


基于这个思路,我做了进一步的测试。于是,我在保留JSON对象不变和全局函数不变的情况下做了一个很小的测试,结果验证是完全正确的

 

我的改动是:



  1. printResult(function(){return theAccumulator.getResult();}); 

其他不变

 

我的想法是,现在这个getResult,由于是以“点”的方式调用了,所以this指针应该会指向点前面的scope,也就是theAccumulator对象,而theAccumulator对象(实实在在的确一定当然)会有getResult()方法,所以,他能解析到。

 

经过测试,果然OK 。




本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/840221,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值