ES6入門基礎知識

一、let和const

1.let

  • 在ES5中沒有塊級作用域這一概念,但在ES6中,新增了let命令,let所聲明的變量只在let命令所在的代碼塊內有效。
  • 暫時性死區(TDZ):let沒有變量聲明提升,在let命令聲明變量之前,該變量都是不可用的
  • 不可重複聲明:let不允許在相同作用域內,重複聲明同一個變量
  • 對於for循環的計數器,很適合用let命令:
    下面的代碼如果使用var,最後輸出的是10
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

上面代碼中,變量i是var命令聲明的,在全局範圍內都有效,所以全局只有一個變量i。每一次循環,變量i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),裏面的i指向的就是全局的i。也就是說,所有數組a的成員裏面的i,指向的都是同一個i,導致運行時輸出的是最後一輪的i的值,也就是 10。

如果使用let,聲明的變量僅在塊級作用域內有效,最後輸出的是 6。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變量,所以最後輸出的是6。你可能會問,如果每一輪循環的變量i都是重新聲明的,那它怎麼知道上一輪循環的值,從而計算出本輪循環的值?這是因爲 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上進行計算。

另外,for循環還有一個特別之處,就是設置循環變量的那部分是一個父作用域,而循環體內部是一個單獨的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}

上面代碼正確運行,輸出了 3 次abc。這表明函數內部的變量i與循環變量i不在同一個作用域,有各自單獨的作用域。

注意:上面代碼如果將let換成var,那麼結果將會不同,只會輸出一次abc,所以只有是let聲明的時候纔會有兩個單獨的作用域。

2.塊級作用域與函數聲明

  • 在ES5中,函數不能在塊級作用域中聲明。ES6規定,塊級作用域之中,函數聲明語句的行爲類似於let,在塊級作用域之外不可引用。
  • 在ES6中的瀏覽器中,它有着自己行爲方式:
1.允許在塊級作用域內聲明函數。
2.函數聲明類似於var,即會提升到全局作用域或函數作用域的頭部。
3.同時,函數聲明還會提升到所在的塊級作用域的頭部。
(function () {
  if (false) {
    function f() { console.log('I am inside!'); }
  }
  f();
}());

//上面的代碼它會這樣解析

(function () {
  var f = undefined;
  if (false) {
    function f() { console.log('I am inside!'); }
  }
  f();
}());
注意:我們應該避免在塊級作用域內聲明函數,要聲明也應該寫成函數表達式,而不是函數聲明。

2.const

  • const聲明一個只讀的變量,一旦聲明,產量的值就不能再改變。
  • const一旦聲明變量,必須立即初始化。
  • const和let一樣,只在聲明的塊級作用域有效,const也存在TDZ,也不能重複聲明。

待續~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章