JavaScript:學習筆記(7)——VAR、LET、CONST三種變量聲明的區別
JavaScript:學習筆記(7)——VAR、LET、CONST三種變量聲明的區別
ES2015(ES6)帶來了許多閃亮的新功能,自2017年以來,許多JavaScript開發人員已經熟悉並開始使用這些功能。雖然這種假設可能是正確的,但仍有可能其中一些功能對某些人來說仍然是一個謎。
ES6帶來的一個新特性是新增了通過使用let、const來聲明變量。在本文中,我們將討論var,let和const的範圍,使用和提升。在您閱讀時,請註意它們之間的差異,我會指出。
VAR
VAR的範圍
範圍本質是意味著這些變量可供使用的位置。var聲明的範圍是全局作用於或者本地函數作用域。當一個var變量聲明在函數外面時它的作用域是全局的,這意味著在整個窗口中可以使用在函數塊外部使用var聲明的任何變量。var變量在函數內聲明時是函數作用域
我們舉一個例子:
<script> var greeter = "Hello"; function hello() { var hi = "Hi"; } </script>
在這裏,greeter是全局範圍的,因為它存在於函數外部,而hello是函數作用域。所以我們不能在函數外部訪問變量hi。所以,如果我們這樣做:
var變量可以重新聲明和更新
這個是比較好理解的
var變量提升
變量提升是什麽意思呢?比如我們看下面這段代碼
當f()執行後,輸出的結果是什麽?可能你會說是日期,因為函數f()中,雖然想對tmp進行字符串賦值,但是被if制止了,所以還是以前的Date類型,其實是錯誤的。這裏涉及到一個問題,就是變量提升(Hoisting),它是一種JavaScript機制,它規定變量和函數聲明在代碼執行之前被移動到其作用域的頂部。
所以,結果就是undefined。
var變量帶來的問題
var有一個弱點。我將使用下面的例子來解釋這一點。
這段代碼看起來是沒有任何問題的,但是卻是一個巨大的隱患,雖然如果您故意要求重新定義greeter,這不是問題,但如果您沒有意識到之前已經定義過變量greeter,則會成為一個問題。如果您在代碼的其他部分使用了greeter,那麽您可能會對可能獲得的輸出感到驚訝。這可能會導致代碼中出現很多錯誤。這就是let和const必要的原因。
也即是說,如果定義在全局作用域的var變量,極有可能對以前定義的同名變量進行覆蓋,從而引發問題,而這一切我們都茫然不知
LET
如果要定義變量,let現在是首選。毫不奇怪,因為它是對var聲明的改進。它還解決了最後一個小標題中提出的這個問題。讓我們考慮為什麽會這樣
Let是塊作用域
塊是由{}限定的代碼塊。一個塊生活在花括號中。花括號內的任何東西都是塊。因此,在帶有let的塊中聲明的變量僅可在該塊中使用。讓我用一個例子解釋一下。
這個是上面例子的改寫,if語句構成了一個塊,在外面我們無法訪問hello,故報錯。
Let可以更新但是不能重新聲明
正如下面例子我們看到的,無法重新定義a變量。
在這裏很明顯兩個a在同一個作用域下,如果我們放在不同的塊中是可以的,但是切記這不是重新聲明,他們隸屬於不同的塊,對每個塊來說都是第一次定義:
Let變量提升
就像var一樣,讓聲明被提升到頂部。與初始化為undefined的var不同,let關鍵字未初始化。因此,如果您在聲明之前嘗試使用let變量,則會出現參考錯誤。
CONST
用const聲明的變量保持常量值。 const聲明與let聲明共享一些相似之處。
const聲明是塊作用域
與let聲明一樣,const聲明只能在聲明的塊中訪問。
const無法更新或重新聲明
因此,每個const變量必須在聲明時初始化。
雖然無法更新const對象,但可以更新此對象的屬性。因此,如果我們聲明一個const對象
CONST變量提升
就像let一樣,const聲明被提升到頂部但未初始化。
總結
讓我們來梳理一下三者的區別
- var聲明是全局作用域或函數作用域,而let和const是塊作用域。
- var變量可以在其範圍內更新和重新聲明;let變量可以更新但不能重新聲明; const變量既不能更新也不能重新聲明。
- 它們全部被提升到其範圍的頂部,但是變量初始化為undefined時,let和const變量不會被初始化。
- 雖然可以聲明var和let而不進行初始化,但必須在聲明期間初始化const。
JavaScript:學習筆記(7)——VAR、LET、CONST三種變量聲明的區別