1. 程式人生 > >ES6 變數、常量宣告總結

ES6 變數、常量宣告總結

前言

較之前ES5,新版本在宣告上有改變,現根據文件教程,總結下不同之處,時常溫習。

一、var  對比  let

  1、作用域不同

    let只在命令所在的程式碼塊 {} 裡有效

    ES5只有全域性作用域和函式作用域,沒有塊級作用域,帶來很多不合理的場景,比如:

    第一種場景,內層變數可能會覆蓋外層變數。

複製程式碼
var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined
複製程式碼

    上面程式碼的原意是,if程式碼塊的外部使用外層的tmp變數,內部使用內層的tmp變數。但是,函式f執行後,輸出結果為undefined,原因在於變數提升,導致內層的tmp變數覆蓋了外層的tmp變數。

    第二種場景,用來計數的迴圈變數洩露為全域性變數。

複製程式碼
var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5
複製程式碼
    上面程式碼中,變數i只用來控制迴圈,但是迴圈結束後,它並沒有消失,洩露成了全域性變數。


   ES6的塊級作用域可以多個巢狀,外層作用域無法訪問內層作用域,內層作用域可以宣告外層作用域的引數。
  
  另外,ES6標準也執行在塊級作用域下宣告函式,而作用域外不可以引用,函式宣告是類似於var還是let,歌瀏覽器可能有自己的處理方式,
所以暫時不建議在塊級作用域下宣告函式

  塊級作用域是一個語句,裡面封裝了若干語句,沒有返回值,現在有一個提案,使得塊級作用域可以變為表示式,也就是說可以返回值,
辦法就是在塊級作用域之前加上do
,使它變為do表示式。

  2、let 不存在變數提升

  3、let 存在暫時性死區

    ES6明確規定,如果區塊中存在letconst命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變數,就會報錯。

總之,在程式碼塊內,使用let命令宣告變數之前,該變數都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。

    ES6 規定暫時性死區和letconst語句不出現變數提升,主要是為了減少執行時錯誤,防止在變數宣告前就使用這個變數,從而導致意料之外的行為。這樣的錯誤在 ES5 是很常見的,現在有了這種規定,避免此類錯誤就很容易了。

    總之,暫時性死區的本質就是,只要一進入當前作用域,所要使用的變數就已經存在了,但是不可獲取,只有等到宣告變數的那一行程式碼出現,才可以獲取和使用該變數。

  4、let 不允許重複宣告變數

    注意:不能在函式裡重複宣告引數,會報錯

二、const 命令

  ES5沒有常量的概念,ES6新增常量

  const 命令宣告一個只讀的常量,一旦宣告,值不可以改變,改變會報錯;只宣告不賦值也會報錯。

  作用域與let 相同,只在所在塊級作用域內有效,其他的特性也相同

  本質上,const 實際上保證的並不是變數的值不可以改動,而是變數指向的那個記憶體地址不可以改動,

  對於簡單型別的資料(數值、字串、布林值),值就儲存在變數指向的那個記憶體地址,因此等同於常量。

  但對於複合型別的資料(主要是物件和陣列),變數指向的記憶體地址,儲存的只是一個指標,const只能保證這個指標是固定的,至於它指向的資料結構是不是可變的,就完全不能控制了。因此,將一個物件宣告為常量必須非常小心。  

三、ES6宣告變數的6中方式

  (ES5只有 var 和function 函式宣告兩種方式)

  1、ES6 宣告方式有var、 let、const、function、import、class

     inport、class 方式的宣告留坑,待填。

     歡迎訪問個人部落格:http://www.cnblogs.com/nana-share/

     歡迎加入  627336556 ,群裡很多大聲可以共同交流學習前端技術

  以上內容參照阮一峰老師的《ECMAScript 6 入門》,會不定期更新;