2、函数作用域和块作用域【Javascript(上)】

120 阅读1分钟

一、立即执行函数表达式(IIFE)

    var a = 2;
    (function IIFE(global) {
        var a = 3;
        console.log(a); // 【注意】:3 
        console.log(global.a); // 【注意】:2
    })(window);
    console.log(a); //【注意】: 2

说明: (function IIFE(){...})()

  • 第一个()括号: 将【函数】变成了【表达式】
  • 第二个()括号: 【执行了这个函数】

二、块作用域

  • let
  • const
  • try... catch

总结:

  • 【 var 变量】,不管写在哪里都是一样的,因为它们都会属于【外部作用域】
  • 注意:【外部作用域】!==【全局作用域】

(一) let 和 var 对比

【例一】的问题:【对于for循环,var i = 0;】为什么在“外部”访问 i 时,结果是 10呢?【重要】

  答:因为 用 var i ,此时 i 会绑定在【外部作用域(“函数作用域”或“全局作用域”)】,因此
  在【for外部】,仍然会有 i,结果为 10
     // 【例一】
     for( var i= 0; i < 10; i++){
         console.log( i ); // 0 , 1, 2, 3, .... 9
     }
     console.log( i ); //【注意】 10

【例二】的问题:【对于for循环,let i = 0;】为什么在“外部”i 会报错呢?【重要】

  答:因为 用 let i ,此时 i 为【块级作用域】,因此,在【for外部】,没法访问到 i    
    // 【例二】
     for( let i= 0; i < 10; i++){
         console.log( i );  // 0 , 1, 2, 3, .... 9
     }
     console.log( '外部:',i );  // 【注意:报错了】Uncaught ReferenceError: i is not defined
     

【例三】的问题:为什么在“if外部”可以访问到 bar 呢?

  答:因为 即使在 "if内部" 声明bar【var bar】, bar 还是属于【if外部作用域】,因此
  【if外部】和【if内部】都可以访问到 bar 变量。
     // 【例三】
     var foo = true;
     if(foo){
         var bar = foo * 2;
         console.log( bar ); // 2
     }
     console.log( bar );// 2
    var foo = true;
    if (foo) {
        var bar = 5;
        console.log(bar); // 5
    }
    console.log(bar); // 5

【例四】的问题:为什么在“if外部”访问 bar 会报错呢?

  答:因为 let 是“块作用域”,尽在“块内部”有效。
      // 【例四】
      var foo = true;
      if(foo){
          let bar = foo * 2;
          console.log( bar ); // 2
      }
      console.log( bar );// 【报错】Uncaught ReferenceError: bar is not defined

【例五】的问题:为什么在“let 变量”前面/上面“访问该变量” 会报错呢?

  答:因为出现了【暂时性死区】, let 是“块作用域”,不会进行“变量提升”。
 console.log( bar); // 【报错了】Uncaught ReferenceError: Cannot access 'bar' before initialization
 let bar = 2;

(二) const

说明:const 用来创建【块作用域】常量,

什么是“常量”?

答:“常量”的值是【固定】的, 【修改值】会【引起错误】,但也有例外(TODO)

(三) try ... catch

说明:在try/catch的【 catch分句 】会创建一个【块作用域】,其中【声明的变量】仅在【catch内部有效】

例子:

     try {
         undefined();         // 执行一个【非法操作】来强制【制造一个“异常”】
     }catch( err ){
         console.log( err );  // 能够“正常执行”此时 catch 声明了【变量err】】仅在catch内部有效
     }
     console.log( err );      // 【报错了】Uncaught ReferenceError: err is not defined