28.作用域

71 阅读2分钟

什么时候作用域

一个变量可以生效的范围。 变量不是在所有地方都可以使用的,而这个变量的使用范围就是我们要说的作用域。js中的作用域分为全局作用域和局部作用域。

全局作用域

全局作用域是最大的作用域
在全局作用域中定义的变量可以在任何地方使用
页面打开的时候,浏览器会自动给我们生成一个全局作用域 window,用var申明的变量和直接申明的函数会直接挂载在window上,可以直接访问

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

局部作用域

局部作用域就是在全局作用域下面开辟出来的一个相对小一些的作用域
在局部作用域中定义的变量只能在这个局部作用域内部使用
在 JS 中只有函数能生成一个局部作用域,别的都不行
每一个函数,都是一个局部作用域\

      function foo() {
        var a = 1;
        console.log(a);
      }
      foo(); // 1
      console.log(a); //  a is not defined

块级作用域

块级作用域是SE6新增的定义,之前js是没有块级作用域的,在{}中使用let,const声明的变量只能在块级作用域里访问,有“暂时性死区”的特性(也就是说声明前不可用)

      if (true) {
        var a = 1;
        let b = 2;
      }
      console.log(a); // 1
      console.log(b); // b is not defined

作用域链

在js中, 函数存在一个隐式属性 [[scopes]], 这个属性用来保存当前函数的执行上下文环境, 由于在数据结构上是链式的, 因此也被称作是作用域链,作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的

      let a = 1,
        b = 2;
      function foo() {
        let a = 3;
        console.log(a); // 3
        console.log(b); // 2
      }
      foo();

我们可以看到打印a的时候会优先选择函数内部的a,b的时候函数内部没有b,就会向上查找b.

js作用域链还可以衍生很多的面试题,但是只有记着作用域链的顺序,依次查找就没问题.闭包的形成也是在作用域外访问了作用域的变量,具体的可以看上一章