es6中容易忽視的細節(一)

你可能不知道的let與const


let

  • var聲明的變量會發生變量提高,在var聲明以前調用該變量會數處undefined,可是let聲明的變量不會發生提高,在聲明以前調用就會報錯es6

    // var 的狀況
    console.log(foo); // 輸出undefined
    var foo = 2;
    
    // let 的狀況
    console.log(bar); // 報錯ReferenceError
    let bar = 2;
  • let不容許在相同的做用域內聲明相同的變量不然會報錯數組

    // 報錯
    function func() {
      let a = 10;
      var a = 1;
    }
  • 塊級做用於有如下兩個用處
    內層變量覆蓋外層變量函數

    var tmp = new Date();  
    
    function f() {
      console.log(tmp);
      if (false) {
        var tmp = 'hello world'; // 這裏會發生變量提高
      }
    }
    
    f(); // undefined

    用來計數的循環變量泄露爲全局變量es5

    var s = 'hello';
    
    for (var i = 0; i < s.length; i++) {
      console.log(s[i]);
    }
    
    console.log(i); // 5
函數聲明與變量聲明的潛規則
  • 容許在塊級做用域內聲明函數(es6規定的在嚴格模式下只有在{}內部才能夠聲明函數)
  • 函數聲明相似於var,即會提高到全局做用域或函數做用域的頭部。
  • 同時,函數聲明還會提高到所在的塊級做用域的頭部,優先於變量的聲明指針

    funtion fun(){};
    var fun;   // 這裏無論先聲明誰fun輸出的永遠都是函數
    fun  //f fun(){}

const

  • const聲明的常量聲明就必須初始化也就是必須賦值,不然就會報錯(如果定義引用類型數據則能夠改變並不會報錯)code

    const obj = {a:{b:2}}
    a.b=3
    obj    // {a:{b:3}}
  • 同let聲明的變量同樣,const不能重複聲明同一變量,同時const也是塊級做用域

小結與擴展

  • const保證的實際上並非變量的值不可改變,而是指變量存放的地址不可改變,對於簡單的數據類型(數字,字符串,boolean)值就保存在變量指向的那個地址(棧區),因此是不可改變的。
  • 可是對於複雜類型的數據(數組、對象),保存的是一個指針,真正的數據是存儲在堆區,只能保證這個指針不會變化,不能保證裏面的數據不發生變化
  • es6的變量聲明方式:var function let const import export
  • 在es5中聲明的全局變量是和頂層對象的屬性對等的
  • 獲取全局對象的方法對象

    var getGlobal = function () {
      if (typeof self !== 'undefined') { return self; }
      if (typeof window !== 'undefined') { return window; }
      if (typeof global !== 'undefined') { return global; }
      throw new Error('unable to locate global object');
    };