JS作用域链

作者: 07120665a058 | 来源:发表于2017-07-25 17:06 被阅读42次
    • 作用域:定义这个变量的区域
    • 作用域链:当前活动对象,加上包含它的所有活动对象
    • 作用域链的作用:是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问

    作用域

    function factory() {
         let name = 'person';
         let intro = function(){
              alert('I am ' + name);
         }
         return intro;
    }
    function app(para){
         let name = para;
         let func = factory();
         func();                  //'I am person'
    }
    app('people');
    

    JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里

    作用域链

    • 变量对象VO分为:全局上下文VO和函数上下文AO
    • 作用域链:本质上是一个指向变量对象的指针列表,它只是引用但不实际包含变量对象Scope = AO|VO + [[Scope]]
    • [[Scope]]是函数的一个属性,处于当前函数上下文之上,在函数创建时存于其中
    let x = 10;
    function foo() {
       let y = 20;
       function bar() {
         let z = 30;
         alert(x +  y + z);
       }
       bar();
    }
    foo(); // 60
    

    全局上下文的变量对象是

    globalContext.VO === Global = {
      x: 10
      foo: <reference to function>
    };
    

    foo创建时,foo[[scope]]属性是

    foo.[[Scope]] = [
      globalContext.VO     
    ];
    

    foo激活时(进入上下文),foo上下文的活动对象是

    fooContext.AO = {
      y: 20,
      bar: <reference to function>
    };
    

    所以,foo上下文的作用域链为

    fooContext.Scope = fooContext.AO + foo.[[Scope]]  = [
      fooContext.AO,           //y=20
      globalContext.VO         //x=10
    ];
    

    函数bar创建时,其[[scope]]

    bar.[[Scope]] = [
      fooContext.AO,
      globalContext.VO
    ];
    

    bar激活时,“bar”上下文的活动对象为

    barContext.AO = {
      z: 30
    };
    

    bar上下文的作用域链为

    barContext.Scope = barContext.AO + bar.[[Scope]] = [
      barContext.AO,            //x=30
      fooContext.AO,            //y=20
      globalContext.VO          //x=10
    ];
    

    总结

    • 函数bar的作用域链里可以访问x,y,z
    • 函数foo的作用域链里可以访问x,y

    参考文章推荐:
    深入理解JavaScript系列(14):作用域链(Scope Chain)

    相关文章

      网友评论

        本文标题:JS作用域链

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