ES 6 : let與const


1.let命令

[ 基本用法 ]

  let命令的用法與var類似,用於聲明一個變量,但是let聲明的變量只能在let所在的代碼塊內有效:

  上述代碼塊中使用let和var聲明了兩個變量。然后在代碼塊之外調用這兩個變量,結果let聲明的變量報錯,var聲明的變量返回了正確的值。說明,let聲明的變量只在其所在代碼塊之內有效

[ 不存在變量提升 ]

  let不像var那樣會發生"變量提升"現象。所以,變量一定要在聲明后使用,否則報錯。

  

暫時性死區 ]

  如果區塊中存在let和const命令,則這個區塊對這些命令聲明的變量從一開始就形成封閉作用域。只要在聲明之前就使用這些變量就會報錯。這在語法上稱為"暫時性死區"簡稱TDZ。

    

  上面的代碼中,在let命令聲明tmp之前,都屬於變量tmp的"死區"。有些"死區"比較隱蔽,不太容易發現:

  報錯的原因是參數x默認等於參數y,而此時y還沒有聲明,屬於"死區"。如果聲明在使用之前就不會報錯:

  總結:暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已存在,但是不可獲取,只有等到聲明變量的那一行代碼出現,才可以獲取和使用該變量。

不允許重復聲明 ]

   let不允許在相同作用域內重復聲明同一個變量。

 

  因此,不能在函數內部重新聲明參數。

2. 塊級作用域

  ES5只有全局作用域和函數作用域,沒有塊級作用域,這會導致以下幾個不合理的場景:

  - 第一種場景,內層變量可能會覆蓋外層變量

  函數f執行后,變量提升導致內層的tmp變量覆蓋了外層的tmp變量。

  - 第二種場景,用來計數的循環變量泄露為全局變量。

  變量i只用來控制循環,但是在循環結束之后它並沒有消失,而是泄露成為了全局變量。

   let實際上為JavaScript新增了塊級作用域。

  上面函數有兩個代碼塊,都聲明了變量n,運行后輸出5。表示外層代碼塊不受內層代碼塊的影響。如果使用var定義變量,則輸出10:

   ES6允許塊級作用域任意嵌套,外層作用域無法讀取內層作用域的變量,但是內層作用域可以定義外層作用域的同名變量。

3. const命令

  const用來聲明常量,一旦聲明,其值不能改變。

  這意味着,一旦用const聲明一個常量,就必須立即初始化,不能留到以后賦值,如果只聲明不賦值就會報錯:

[ const ]

  • 作用域與let命令相同:只在聲明所在的塊級作用域內有效。

  • 聲明的常量也不能提升,同樣存在暫時性死區。

  • 不可以重復聲明常量。

[ const聲明復合類型變量 ]

  對於復合類型的變量,變量名不指向數據,而是指向數據所在的地址。const命令只是保證變量名指向的地址不變,而不保證該地址的數據不變。

  

  上面代碼中,常量foo存儲的是一個地址,指向一個對象。不可變的只是這個地址,即不能把foo指向另一個地址,但對象本身是可變的,所以依然可以為其添加新屬性。但如果將另一個地址賦值給foo,就會報錯:

  如果真的想將對象凍結,使其不可添加新屬性,應該使用Object.freeze方法。

  給foo添加新屬性不起效果。

  除了凍結對象本身,對象的屬性也應該一起凍結,下面是一個將對象徹底凍結的函數:

  對象被徹底凍結之后,屬性也無法被修改。

 4. 全局對象屬性

  全局對象是最頂層的對象,在瀏覽器環境中指的是window對象。在ES5中,全局對象的屬性與全局變量是等價的。

  這種規定容易在不知不覺中就創建了全局變量,ES6為了改變這一點,一方面規定,var命令和function命令聲明的全局變量依舊是全局對象的屬性;另一方面規定,let命令、const命令和class命令聲明的全局變量不屬於全局對象的屬性。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM