作用域和自由变量

121 阅读2分钟

作用域和自由变量

1. 作用域

作用域就是限制变量在代码中可以被访问的范围。

作用域分为全局作用域、函数作用域和块级作用域(ES6新增)。

1. 全局作用域:

全局作用域是最外层的作用域,比如script标签下的第一层:下面这个红框圈起来的就是全局作用域,a就是声明在全局作用域里的变量,可以在整个全局作用域内访问。

1736168997963.png 或者是整个js文件:整个js文件就是一个全局作用域。

image.png

2. 函数作用域

函数作用域指的是函数内部的作用域,声明在函数作用域内部的变量只能在函数作用域内访问,比如下面代码:声明在test函数内部的变量a,在外面是访问不到的。

    function test() {
      let a = 2;
    }
    console.log(a); // 访问不到

3. 块级作用域

因为ES6中let关键字的出现,块级作用域也随之产生,{}所包含的区域就是块级作用域。

    {
      let a = 1;
    }
    console.log(a); // 访问不到

类似于if(){}的都算是块级作用域。

是不是跟函数作用域有点类似,但是函数作用域是里面的变量声明无论是let声明还是var声明,外界都无法访问,而块级作用域里只有let声明的变量,外界才无法访问,var声明的变量外界是可以访问的。

    {
      var a = 1;
    }
    console.log(a); // 1

4. 作用域链

下文代码中有两个函数作用域:

    let a0 = 0;

    function fn1() {
      let a1 = 1;

      function fn2() {
        let a2 = 2;
        console.log(a1); // 1
      }
      fn2();
    }

    fn1();

可以看到在fn2函数中打印a1变量,是能够成功访问的,但是fn2的函数作用域并没有a1这个变量,但是fn2的父级作用域里有,fn2里访问不到变量a1,就会往父级作用域去找,如果父级作用域也没有就再往上一层找,这就是作用域链。

2. 自由变量

在当前作用域里面有使用但是没有声明的就叫做自由变量,像前文介绍作用域链时举例的变量a1就是自由变量。