JavaScript變量中var,let和const的區別
前言
JavaScript中一共有3種用來聲明變量的關鍵字,分別是var、let和const。
其中var關鍵字是ES5時代的產物,由於ES5對變量的約束很寬松,使用var來聲明變量時經常會出現一些預料之外的問題。 ES6為瞭使變量的定義更加規范,提出瞭let和const這兩個關鍵字。
因此要解釋清楚這三個的區別,首先要從ES5時代和ES6時代的差別說起,主要是var和let的區別。
ES5與ES6的區別
1. 作用域
使用不同的關鍵字來聲明變量,主要就是對變量的作用域有不同的限制,因此var和let最主要的區別就是變量作用域的區別。
- var聲明的范圍是函數作用域,函數體之外無法訪問到函數體內聲明的var變量。
做題的時候經常會有在全局和函數體內聲明同名變量的場景,要知道不同作用域的變量是不會互相幹擾的。
var a = 10; function logA() { var a = 20; console.log(a); // 20 } console.log(a); // 10
- let聲明的范圍是塊作用域,塊作用域是函數作用域的子集,可以使用花括號
{...}
來限定塊級作用域。
2. 全局屬性
在全局作用域下使用var和let聲明變量,變量都是會在頁面的聲明周期內存續。
但是使用var聲明的變量會成為window對象的屬性,使用let聲明則不會。
3. 變量提升與暫時性死區
- var聲明存在變量提升的行為。
變量的聲明、初始化和賦值被分為三步進行,對於var變量,聲明和初始化會被提升到作用域的頂部。
也就是說,編譯器在遇到var聲明時,會先在作用域頂部聲明一個var變量並將其初始化為undefined值。
因此在代碼執行流遇到var聲明語句之前訪問var變量並不會報錯,而是會訪問到undefined值。
(function example() { console.log(age); // undefined var age = 20; })(); // 相當於 (function example() { var age; console.log(age); // undefined age = 20; })();
- ES6對先訪問後聲明變量的行為做瞭約束,因此let和const聲明會存在TDZ暫時性死區。
即JavaScript引擎在編譯時如果遇到let和const聲明,會將它們放入暫時性死區以阻止訪問,隻有在執行到變量聲明的語句後,才會將變量從TDZ中移出。
因此如果在變量聲明語句之前訪問變量,相當於企圖訪問TDZ中的變量,JavaScript會拋出運行時錯誤ReferenceError
。
ES5的變量提升和ES6的暫時性死區的區別還有一個“副作用”就是改變瞭
typeof
操作對於變量的訪問性。已知在ES5時對於未聲明變量唯一的安全操作是
typeof
,會返回undefined值。TDZ的出現導致即使使用
typeof
,也不能在let和const聲明語句執行之前訪問let和const變量,依然會報ReferenceError
。
4. 重復聲明
- var聲明是允許重復的,可以重復使用var關鍵字來聲明同名變量,後來聲明的變量值會覆蓋之前的值。
- 為瞭阻止重復聲明變量這個容易讓人迷惑的行為,ES6限制瞭let和const聲明的變量都是不可重復的,如果重復聲明會報
SyntaxError
錯誤。
這個限制不僅體現在let聲明對let聲明,如果想用let去重復聲明var變量也是不被允許的。
let與const的區別
1. 常量
同樣都是ES6的變量聲明關鍵字,let和const的區別就在於使用const聲明創建的是一個值的隻讀引用。
隻讀引用意味著對於原始值來說,const聲明不可以再重新賦值;
對於引用值來說,const聲明不可以再修改引用,但是可以修改對象的屬性值或者數組內部的值。
最佳實踐
- 盡量不使用var。因為let和const已經可以替代var的位置,滿足開發需求,順便還規避瞭很多不必要的問題。
- 優先使用const聲明,let聲明次之。const聲明有點像保護變量的機制,它能預防和阻止預期之外的變量修改。 對於有修改需求的變量,就使用let聲明。
到此這篇關於JavaScript變量中var,let和const的區別的文章就介紹到這瞭,更多相關JS var,let,const內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- JavaScript三大變量聲明詳析
- 基於JavaScript ES新特性let與const關鍵字
- 簡單談談JavaScript變量提升
- 淺談JS中var,let和const的區別
- javascript的var與let,const之間的區別詳解