前言:
在早期的ES標準中,只有var一種聲明類型。經過了好幾年的探索,歐洲電子協會終于在2015年發布了ES6標準,新增加了let和const兩個重要關鍵字。如今對于大多數的互聯網企業來說,他們也已經慢慢采用了ES6規范。所以,如果你在通篇js中只使用var去聲明甚至不去聲明,那么你的js代碼是非常糟糕且難于理解的。在真正的互聯網企業中,你這種行為也是會被痛批的。(此處應有笑臉)所以我們很有必要去深入地了解var、let和const之間的區別,做到規范寫代碼。
-
首先我們看一下下面這份表:
var let const 初始值 不需要 不需要 需要 重復聲明 允許 不允許 不允許 變量提升 允許 不允許 不允許 作用域 全局、局部 塊級 塊級 暫存死區 不會 會 會
!!!敲重點,這個表格大家一定背熟,面試時基本都會問到。
下面我們結合代碼來一個個詳細地介紹它們的區別,做到知其然,亦知其所以然。
1、初始值
(1)var、let聲明變量可以賦值也可以不賦值:
var initialValue;//initialValue還沒賦值,合法 var initialValue = 2;//initalValue = 2,合法
let initialValue;//initialValue還沒賦值,合法 let initialValue = 3;//initialValue = 3,合法
(2)const聲明變量同時必須賦值:
const initialValue;//initialValue還沒賦值,不合法 const initialValue = 4;//initialValue = 4,合法
2、重復聲明
(1)var允許重復聲明:
<script> var i = 10;//i = 10 var i = 2;//此時i = 2 var i = 5;//此時i = 5 if(1) { var i = 100;//此時i = 100 } console.log(i);//此時i = 100 </script>
注:所以大家發現了嗎,當我使用var聲明一個變量時,我可以對同一個變量進行賦值,其變量最終的值為最后聲明的那次。
(2)let、const不允許重復聲明:
<script> let a = 100;//a = 100,合法 let a = 10;//不合法 const x = 20;//x = 20,合法 const x = 2;//不合法 </script>
注:從上面代碼可以看出,當我們使用let或者const聲明一個變量的值時,這個變量就不能再使用let、const去聲明了,但是并不代表不能再賦值。這是兩個不一樣的意思,var、let聲明的是可以重新賦值的,而const是不能重新賦值的。
3、變量提升
(1)var允許變量提升:
<script> x = 10; var x; console.log(x);//此時控制臺輸出x = 10; </script>
注:在JavaScript中,允許var關鍵字聲明的變量可以先使用后再聲明。
(2)let、const不允許變量提升:
<script> x = 10; let x; console.log(x);//此時控制臺輸出undefined y = 10; const y; console.log(y);//報錯,因為y沒有賦值 </script>
注:從上面代碼可以看出let和const不允許變量先使用后再聲明。但是在日常的編寫代碼習慣中,很少有人會先使用變量后再聲明,因為這是不符合代碼邏輯的。因此,重在了解,這個對我們代碼編寫沒多大用處。
4、作用域
(1)var的作用域包含全局和局部,除了塊級之外(什么是塊級作用域下面會說到):
<script> var x = 1;//在函數外聲明的變量的作用域是全局的 for(let i = 0;i<5;i++){ var x = 100;//在函數內聲明的變量的作用域是局部的 } console.log(x);//可以訪問,x=100 </script>
(2)let、const的作用在塊級內:
<script> let x = 1; for(let i=0;i<1;i++){ let x = 5; console.log(x);//x=5 } console.log(x);//x=1 </script>
注:從上面代碼可以看出,像{}就叫做塊,使用let聲明的變量互不影響,變量只在其作用域內有意義。至于const的也是同理,這里不再贅述。一般我們使用const都是在全局中聲明常量。
5、暫存死區
(1)var不會暫存死區:
<script> var a = 10; if(1){ a = 100; var a; } console.log(a);//控制臺輸出a = 100 </script>
(2)let和const會暫存死區:
<script> let a = 10; if(1){ a = 100; let a; } console.log(a);//報錯,找不到a const b = 20; if(1){ b = 200; const b; } console.log(b);//報錯,找不到b </script>
注:如果代碼塊中存在let或者const命令,那么塊就會對這些命令聲明的變量形成一個封閉作用域,因此在聲明前使用變量就會出錯,而var就不會。但是在代碼編寫中也很少會這樣編寫,重在了解。
const關鍵字
前面有提到const在聲明變量時必須賦值,也就是初始化,且初始化不能再更改。例如:
<script> const a = 1111; a = 100;//報錯 </script>
但是本質上const聲明的變量并不是常量,并不是一定不能改變的,真正的含義是定義了一個常量引用的一個值,當我們使用const初始化一個數組或者對象時,其實是可以改變的,例如:
const person ={ id:1, name:'Tang_Xiaokang', age:20, tele:123456789 }; person.id = 4;//此時對象person的屬性id已經改為4 console.log(person.id);//輸出4 person ={ id:34, name:'tangxiaokang', age:100, tele:987654321 };//此時會報錯
注:從上面代碼可以看到,對一個對象使用const進行初始化時,整個對象是不可以重新賦值的,但是我們是可以修改對象里面的每一個屬性的。因為對象里面的屬性并沒有使用const關鍵字。(重點!!!)
最后,經過上面的學習,相信你已經充分了解它們之間的區別。但是,學習了理論還不夠,我們更要在日常編寫代碼中使用才行。所以,我們應該如何正確的使用這些關鍵字呢?下面我再簡單講一下它們的使用場景:
const PI = 3.14;
var x = 100;
let y = 20;
for(let i = 0;i<100;i++){
//一些代碼...
}
所以,它們的優先級可以是:const > let > var。用const聲明變量一般表明了其變量是不能再改變了,也就是通常講的常量。對于var,一般我們可以在塊或函數外面使用,而在塊級里面我們一般使用let較多。自從ES6標準提出后,let其實完全可以取代var,因為兩者作用差不多,重點是let沒有副作用!!!