了解作用域对程序执行的影响及作用域链的查找机制,使用闭包函数创建隔离作用域避免全局变量污染。

作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问,作用域分为全局作用域和局部作用域。

局部作用域

局部作用域分为函数作用域和块作用域

函数作用域

在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。

  1. <script>
  2. // 声明 counter 函数
  3. function counter(x, y) {
  4. // 函数内部声明的变量
  5. let s = x + y;
  6. console.log(s); // 18
  7. }
  8. // 设用 counter 函数
  9. counter(10, 8);
  10. // 访问变量 s
  11. console.log(s); // 报错
  12. </script>

总结:

  1. 函数内部声明的变量,在函数外部无法被访问
  2. 函数的参数也是函数内部的局部变量
  3. 不同函数内部声明的变量无法互相访问
  4. 函数执行完毕后,函数内部的变量实际被清空了

    块作用域

    在 JavaScript 中使用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。

    1. <script>
    2. {
    3. // age 只能在该代码块中被访问
    4. let age = 18;
    5. console.log(age); // 正常
    6. }
    7. // 超出了 age 的作用域
    8. console.log(age); // 报错
    9. let flag = true;
    10. if(flag) {
    11. // str 只能在该代码块中被访问
    12. let str = 'hello world!';
    13. console.log(str); // 正常
    14. }
    15. // 超出了 age 的作用域
    16. console.log(str); // 报错
    17. for(let t = 1; t <= 6; t++) {
    18. // t 只能在该代码块中被访问
    19. console.log(t); // 正常
    20. }
    21. // 超出了 t 的作用域
    22. console.log(t); // 报错
    23. </script>

    JavaScript 中除了变量外还有常量,常量与变量本质的区别是【常量必须要有值且不允许被重新赋值】,常量值为对象时其属性和方法允许重新赋值。

    1. <script>
    2. // 必须要有值
    3. const version = '1.0.0';
    4. // 不能重新赋值
    5. // version = '1.0.1';
    6. // 常量值为对象类型
    7. const user = {
    8. name: '小明',
    9. age: 18
    10. }
    11. // 不能重新赋值
    12. user = {};
    13. // 属性和方法允许被修改
    14. user.name = '小小明';
    15. user.gender = '男';
    16. </script>

    总结:

  5. let 声明的变量会产生块作用域,var 不会产生块作用域

  6. const 声明的常量也会产生块作用域
  7. 不同代码块之间的变量无法互相访问
  8. 推荐使用 letconst

注:开发中 letconst 经常不加区分的使用,如果担心某个值会不小被修改时,则只能使用 const 声明成常量。

关键字 块级作用域 变量提升 初始值 更改值 通过window调用
let ×√ - Yes No
const ×√ Yes No No
var × - Yes Yes