美文网首页
关于作用域链

关于作用域链

作者: 小御茶 | 来源:发表于2018-05-13 11:24 被阅读0次

    执行环境(execution context)

    执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为。每个执行环境都有与之对应的变量对象(variable object),保存着该环境中定义的所有变量和函数。我们无法通过代码来访问变量对象,但是解析器在处理数据时会在后台使用到它。

    执行环境有全局执行环境(也称全局环境)和函数执行环境之分。执行环境如其名是在运行和执行代码的时候才存在的,所以我们运行浏览器的时候会创建全局的执行环境,在调用函数时,会创建函数执行环境。

    全局执行环境

    全局执行环境是最外围的一个执行环境,在web浏览器中,我们可以认为他是window对象,因此所有的全局变量和函数都是作为window对象的属性和方法创建的。代码载入浏览器时,全局环境被创建,关闭网页或者关闭浏览时全局环境被销毁。

    函数执行环境

    每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就被推入一个环境栈中,当函数执行完毕后,栈将其环境弹出,把控制权返回给之前的执行环境。

    作用域、作用域链

    全局作用域(globe scope)和局部作用域(local scope)

    全局作用域可以在代码中的任何地方都能被访问
    另外,在函数中声明变量时,如果省略 var 操作符,那么声明的变量就是全局变量,拥有全局作用域,但是不推荐这种做法,因为在局部作用域中很难维护定义的全局变量。
    再者,window对象的内置属性都拥有全局作用域。
    局部作用域一般只在固定的代码片段内可以访问得到

    作用域链(scope chain)

    全局作用域和局部作用域中变量的访问权限,其实是由作用域链决定的。
    每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链。作用域链是函数被创建的作用域中对象的集合。作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问。
    作用域链的最前端始终是当前执行的代码所在环境的变量对象(如果该环境是函数,则将其活动对象作为变量对象),下一个变量对象来自包含环境(包含当前还行环境的环境),下一个变量对象来自包含环境的包含环境,依次往上,直到全局执行环境的变量对象。全局执行环境的变量对象始终是作用域链中的最后一个对象。
    标识符解析是沿着作用域一级一级的向上搜索标识符的过程。搜索过程始终是从作用域的前端逐地向后回溯,直到找到标识符(找不到,就会导致错误发生)。

    var a = 1
    function fn1(){
      function fn2(){
        console.log(a)
      }
      function fn3(){
        var a = 4
        fn2()
      }
      var a = 2
      return fn3
    }
    var fn = fn1()
    fn() //输出多少
    
    1. 第10行 fn()的值为fn1()的值
    2. 第9行 fn1()返回fn3
    3. 第7行 fn3调用fn2()
    4. 第4行fn2()输出a,在局部环境里找不到a的值,到上级找到a=2
    var a = 1
    function fn1(){
    
      function fn3(){
        function fn2(){
          console.log(a)
        }
        fn2()
        var a = 4
      }
      var a = 2
      return fn3
    }
    var fn = fn1()
    fn() //输出多少
    
    1. 第10行 fn()的值为fn1()的值
    2. 第9行 fn1()的值为调用fn3
    3. 第6行 fn3()的值为调用fn2
    4. 第5行fn2()在局部环境里找不到a的值,到上一级找到 var a,由于变量提升,因此为未定义

    相关文章

      网友评论

          本文标题:关于作用域链

          本文链接:https://www.haomeiwen.com/subject/dftldftx.html