用一个例子理解JS作用链

106 阅读2分钟

作用域链

  1. 特点

    作用域链并非根据调用嵌套形成的,而是根据函数创建嵌套形成作用域链,也就是函数的书写位置形成作用域链,因此称为词法作用域。

    函数创建时,函数的作用域链会创建一个指向函数的创建时的文本环境对象

    函数执行时,函数的作用域链会将函数变量对象放在函数作用域链的首端

    函数执行时,查找变量是沿着作用域链逐个逐个变量对象进行查找的

  2. 例子

    function foo() {
        console.log(a);//2
    }
    function bar() {
        var a = 3;
        foo();
    }
    var a = 2;
    bar();
    
    1. 执行代码之前,js解析器会首先创建一个全局执行环境,该环境的作用域链指向全局变量对象,同时foo函数预解析指向一个foo 指向foo执行环境,该执行环境有该函数作用域链,该作用域链声明时会指向函数创建的环境变量对象(函数的出生地),bar函数也是如此

    2. 执行bar()之前 会创建bar的函数变量对象,该函数变量对象排在bar的作用域首端,表示在bar执行代码时,先会bar函数变量对象中,如果找不到再往作用域链上找

    3. 执行foo函数创建foo的函数变量对象,该函数变量对象排在foo的作用域首端,当执行console.log(a) 先去foo的函数变量对象找不到,然后去全局变量对象中找,找a=2

      函数foo并没有在bar函数内声明创建,所以函数foo的作用域链不会指向bar变量对象