• 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.

  • 相关阅读:
    Unity WebGL MoonSharp崩溃问题
    UISprite(NGUI)扩展 图片镂空
    自动化交易机器人Beta猪
    如何成为一个真正在路上的Linuxer
    课堂里学不到的C与C++那些事(一)
    Android ART运行时与Dalvik虚拟机
    用Dockerfile构建docker image
    论docker中 CMD 与 ENTRYPOINT 的区别
    sshfs远程文件系统挂载
    docker镜像与容器存储结构分析
  • 原文地址:https://www.cnblogs.com/dont27/p/3779118.html
Copyright © 2020-2023  润新知