1. 程式人生 > >淺談ES的let和const及其區別

淺談ES的let和const及其區別

淺談ES的let和const

ES6提供了let和const的新特性,同時也是新的變數宣告方式,它能解決以往var變數宣告存在的隱性弊端問題。

Let

let的出現,解決了ES中塊級作用域的需求。回顧在這之前,Js並沒有沒什麼類似其他程式語言中塊級作用域的概念(比如var宣告的全域性變數屬於全域性物件的屬性,即意味著我們可以通過window.變數名的方式訪問到),因此這也導致了很多變數汙染的問題,進而導致產生更多奇怪的問題。

塊級作用域
for (var i = 0; i < 10; i++) {
    console.log(i)
}
console.log(i) // i=10
for (let j = 0; j < 10; j++) {
    console.log(j)
}
console.log(j) // ReferenceError: j is not defined

如上所示,如果我們在迴圈內部使用var宣告一個變數的話,當迴圈結束後,該變數並沒有被回收,仍然能被使用,出現了迴圈中的亂象。而當我們使用let的時候,當離開這個塊的時候,該變數就會回收,因此繼續使用就會報錯。

暫時性死區
var i = 5;
(function a() {
  console.log(i) // undefined
  var i = 10
})()

let j = 55;
(function b() {
  console.log(j) // ReferenceError: j is not defined
  let j = 77
})()

看以上程式碼,由於var它具有變數提升的功能,所以該宣告語句會移到最上面執行,也就是等價於以下程式碼:

var i = 5;
(function a() {
  var i
  console.log(i) // undefined
  i = 10
})()

let j = 5;
(function b() {
  console.log(j) // ReferenceError: j is not defined
  let j = 10
})()

但是,如果將var換成let的話卻會報錯,也就是說let並不具備變數提升的特性。

這個特性叫做臨時性死區,也可以把它當成變數提升的一種特殊情況。也就是說,當你在一個塊裡面,利用let宣告一個變數的時候,在塊的開始部分到該變數的宣告語句之間,我們稱之為臨時性死區,你不可以在這個區域內使用該變數,直到遇到其let

語句為止。比如:

var i = 5;   // j的臨時性死區
(function a() { 
  var i
  console.log(i) // undefined
  i = 10
})() // j的臨時性死區
// j的臨時性死區
let j = 5; // 接下來可以使用let了
console.log(j)
console.log(j+10)
(function b() {
  console.log(j) // 新的j的臨時性死區
  let j = 50 //又有一個宣告語句,從這個函式的開始部分到這裡,都是新的j的臨時性死區
})()

之所以說它是變數提升的一種特殊情況,是因為無論你在塊的哪一個地方利用let聲明瞭一個變數,都會產生一個從塊的開始部分到該變數宣告語句的臨時性死區。

對var或者是直接宣告全域性變數來說,變數都可以未宣告或者在宣告語句之前就使用,而使用了let之後,該變數必須在其宣告語句後,才能使用,否則就會報錯。這就在一定程度上避免了變數汙染的情況。

const

const,顧名思義,就是宣告一個常量。

它有以下特點:
1.必須初始化
2.不可重複宣告
3.作用域:塊級作用域
4.不存在變數提升現象(與let相同)

constlet宣告的變數很類似,不同之處在於變數的宣告和初始化必須一起進行,且之後值不可隨意修改。只宣告不賦值也會報錯:Uncaught SyntaxError: Missing initializer in const declaration

對於宣告數值的可變性,有以下兩種情況:

當變數型別為number,string,boolean,null時,數值是常量,即在初始化之後不允許修改,否則報錯 Uncaught TypeError: Assignment to constant variable
當變數為物件,陣列時,其內容可以修改,因為物件,陣列等變數存放的是地址,地址不允許修改,但是地址裡面存放的內容是可以修改的。