首先有个原则:

就是在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 。