前言:
在早期的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没有副作用!!!