作用域

js的作用域有3种,分别是全局作用域,局部作用域,块级作用域(ES6新增)。

全局作用域:在函数function以外定义的变量是全局变量,具有全局作用域,在任何地方都可以访问

        let a = 1;
        function x() {
            console.log(a);
        }
        x();    

x()函数中并未声明变量a,但上面代码执行后会打印出1

局部作用域:在函数function内定义的变量为局部变量,具有局部作用域,函数内部都可以访问

       function x() {
            let a = 1;
        }
        console.log(a);

x()函数中定义了变量a,但在函数外部打印变量a会报错,提示a没有定义

块级作用域:{}括号内定义的变量,具有块级作用域,{}以外无法访问,比如if判断和for循环中

      if (true) {
           let a = 1;
       }
       console.log(a);

打印变量a会报错,提示a没有定义

 

自由变量

其实除上述3种变量外,还有一种特殊的变量叫自由变量。

自由变量:一个变量在当前作用域中(也就是上述3种作用域)没有被定义,但却被使用了

       let a = 1;
       function x() {
           let b = 2;
           function y() {
                console.log(a + b);
           }
           y();
       }
      x();

x()函数执行后,结果为3,为什么y()中没有定义变量ab,但控制台却能打印出结果3呢?

 

因为自由变量会像上级作用域一层一层的寻找,直至找到为止。所以当y()函数执行打印a+b时,

虽然y()函数中没有定义变量a和b,但它会往上一级去寻找,这里的上一级是x()函数,但它只定义了变量b,

因此会接着往上寻找,最后找到了x()函数外定义的全局变量a。

注:如果全局作用域都没有找到,则会报错xxx is not defined

 

闭包

闭包可简单理解为作用域应用的2种特别情况:

1. 函数作为返回值被返回

2. 函数作为参数被传递

  

上面2个示例执行代码后,a的值都为100, 你可能会有疑惑, 为什么a都是100呢?

明明在函数执行之前已经重新定义了变量a的值,下面用大神总结的一句话就可迎刃而解

总结:所有自由变量的查找是在函数定义的地方,向上级作用域一层一层往上查找,而不是在执行的地方

 

红色框部分就是函数定义的地方,然后向上级作用域寻找,a的值为100

 

 

有需要的朋友可以领取支付宝到店红包,能省一点是一点