Skip to main content

变量的作用域

Q:什么是作用域?

  • A:程序源代码中定义变量的区域。

Q:有什么用?

  • A:规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

Q:变量作用域有哪些?

  • A:

    • 全局变量:函数内部可以直接读取全局变量。

      var n=999;

      function f1(){
      alert(n);
      }

      f1(); // 999
    • 局部变量:函数外部无法读取函数内的局部变量。

      function f1(){
      var n=999;
      }

      alert(n); // error

Q:若不使用var命令,会声明什么变量?

  • A:全局变量

    function f1(){
    n=999;
    }

    f1();

    alert(n); // 999

Q:如何从外部读取局部变量?

  • A:使用闭包——在函数的内部,再定义一个函数。

    function f1(){

    var n=999;

    function f2(){
    alert(n); // 999
    }

    }

Q:var的作用域是什么?

  • A:

    • 如果一个变量在函数体内部声明,则该变量的作用域为整个函数体,在函数体外不可引用该变量

      'use strict';

      function foo() {
      //在函数体内部声明
      var x = 1;
      x = x + 1;
      }

      x = x + 2; // ReferenceError! 无法在函数体外引用变量x
    • 如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。(即:不同函数内部的同名变量互相独立,互不影响)

      'use strict';

      function foo() {
      var x = 1;
      x = x + 1;
      }

      function bar() {
      var x = 'A';
      x = x + 'B';
      }

函数作用域

Q:哪些变量属于函数作用域?

  • A:在某个函数内的变量即从属于当前函数作用域

Q:特点是什么?

  • A:内部函数可以访问外部函数定义的变量,反过来则不行

    'use strict';

    function foo() {
    var x = 1;
    function bar() {
    // bar可以访问foo的变量x!
    var y = x + 1;
    }
    // ReferenceError! foo不可以访问bar的变量y!
    var z = y + 1;
    }

全局作用域

Q:哪些变量具有全局作用域?

  • A:不在任何函数内定义的变量就具有全局作用域。

Q:全局作用域的变量在哪里可以访问到?

  • A:window中。全局作用域的变量实际上被绑定到window的一个属性

Q:全局作用域的特点是什么?

  • A:
    • JavaScript实际上只有一个全局作用域。
    • 任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误。

块级作用域

Q:如何使变量具有块级作用域?

  • A:用letconst替代var可以申明一个块级作用域的变量

词法作用域(静态作用域)

Q:是什么?

  • A:一个符号参照到语境中符号名字出现的地方,局部变量缺省有着词法作用域。

Q:采用静态作用域与动态作用域处理流程?

  • A:

    【示例】

    var value = 1;

    function foo() {
    console.log(value);
    }

    function bar() {
    var value = 2;
    foo();
    }

    bar();
    • 采用静态作用域时(按顺序而去获取)
      • 执行foo函数,先从foo函数内部查找是否有局部变量value,
        • 如果没有,就根据书写的位置,查找上面一层的代码,在这里是全局作用域,也就是value等于1,所以最后会打印1
    • 采用动态作用域时(随着函数调用而去获取)
      • 执行foo函数,依然是从foo函数内部查找是否有局部变量value。
        • 如果没有,就从调用函数的作用域,也就是bar函数内部查找value变量,所以最后会打印2