淺談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相同)
const
和let
宣告的變數很類似,不同之處在於變數的宣告和初始化必須一起進行,且之後值不可隨意修改。只宣告不賦值也會報錯:Uncaught SyntaxError: Missing initializer in const declaration。
對於宣告數值的可變性,有以下兩種情況:
當變數型別為number,string,boolean,null時,數值是常量,即在初始化之後不允許修改,否則報錯 Uncaught TypeError: Assignment to constant variable。
當變數為物件,陣列時,其內容可以修改,因為物件,陣列等變數存放的是地址,地址不允許修改,但是地址裡面存放的內容是可以修改的。