function变量困惑

1 var name = "The Window"; 
2 var object = { 
3     name : "My Object", 
4     getNameFunc : function(){
5      return function(){ 
6          return this.name; 
7          }; 
8     } 
9 };

一个经典的代码,在高程也出现过的,意在说明 this 和 闭包变量作用域。

以前写过一篇记录一下,最近在sf看到一博客文章,又突然陷入深思。

http://blog.segmentfault.com/findingea/1190000000537129

首先,说一下2个关键点:

1.function的作用域:在function中访问一变量,首先看function执行体内是否存在该变量,不存在,则往function的调用环境,去查询,如果是多层调用,则会遵循内部找不到就往外部查找,一直到全局作用域,这也就是作用域链。

1.1一般说来,闭包,即内部函数调用了外部函数的变量,并返回自身给外部使用,此时,即可访问到外部函数的变量,这里能不能说其实也是套用了所谓的作用域链原理呢。

 

2. function的作用域内,本身执行体的执行环境包含参数arguments和this两个自带的,不会导致需要去外部找变量,上面的经典问题中,this.name之所以返回的是 the window 即全局变量,那是因为function自身的调用环境决定的,这个return的闭包,不属于object对象本身的属性,因此,自然而然,其调用主题是全局window。

通过需要后,即可达到访问object.name的效果.

 1 var name = "The Window"; 
 2 var object = { 
 3     name : "My Object", 
 4     getNameFunc : function(){
 5           var that = this;
 6      return function(){ 
 7          return that.name; 
 8          }; 
 9     } 
10 };

这里用that存了this,getNameFunc本身就是object的属性,因此this指向的是object,而that作为最底层的function的外部函数的作用域之一,刚好function内部没有that的申明,所以自然内部调用that访问的就是外部函数的作用域的that。

 

而我本来觉得这样好理解,突然想,那么不要this呢?

1 var name = "The Window"; 
2 var object = { 
3     name : "My Object", 
4     getNameFunc : function(){
5      return function(){ 
6          return name; 
7          }; 
8     } 
9 };

一开始以为,根据作用域链,最终得到的name应该是object.name,结果一运行,不对,为什么呢?

一开始搞不明白。

但是,回想起来,首先,getNameFunc这里如果调用name同样得到的是全局的name.  想想,假设我加一句代码进去,

 1 var name = "The Window"; 
 2 var object = { 
 3     name : "My Object", 
 4     getNameFunc : function(){
 5              console.log(name); //这里name是全局name
 6      return function(){ 
 7          return name; 
 8          }; 
 9     } 
10 };

正如我注释的那里,这里直接调用name,跟调用this.name的不同,在于this.name是对象的属性,直接调用,则是查找作用域里声明的name,明显与对象属性不是同一个概念,正如 

var name = 0; 和 obj.name="dont"; 不能相提并论,不知道这么解释对不对。

也正因为作用域里不存在独立的name声明,因此最终找到的是全局的作用域声明的name: The Window.

posted @ 2014-06-10 22:12 Dont 阅读(...) 评论(...) 编辑 收藏