const,let的出现就是为了替换var,解决使用var出现的不必要的bug。
var的缺点?
变量提升
因为js的变量提升机制,var没有块级作用域的概念,不管在哪个块声明了变量,其他地方都可以访问到,这样就可能造成迷惑行为。
而let和const就不会出现这种问题
function fun(){
//js的变量提升机制,实际上声明变量是在这一行就被声明了,所以在if块外面,也可以访问到a
console.log(a) //undefined //如果将var改成let,这里就会报错
if(true){
var a = 2
console.log(a) //2
}
else{
console.log(a) //如果走到了else,这里不会报错,可以访问到a,不过这里a就没有被赋值所以打印undefined //如果将var改成let,这里就会报错
}
console.log(a) //2 //如果将var改成let,这里就会报错
}
重复声明变量
可以在同一作用域重复声明变量,之后声明的变量会导致这个变量的全局修改,这样做的坏处就是如果在其他地方声明了相同的变量, 你修改了它的值,会导致其他相同的变量也被修改,出现意想不到的bug
因为js的变量提升机制,将所有变量的声明提升到作用域顶级,所以可能存在相同的变量,如果不允许重复声明,那么就会报错。而且当遇到重复声明时,编译器会自动忽略声明,直接赋值。
所以为了避免这种意想不到的bug,出现了let和const
function fun(){
var a = 1
if(true){
var a = 2
var a = 3 //这里会将上面两个声明都覆盖掉,将之前所有出现a的地方的值都改为3 //如果将这里 改为let,那么这里就会报错,不可以在这里重复声明a变量
console.log(a) //3
}
console.log(a) //3 //如果这里的声明变量使用let,那么打印为1,if中的重新声明不会影响到上层作用域
}
为什么const / let 会替代var
const let是什么?
const,let时ES6新出现的声明关键字,使用他们声明变量会减少程序出现不必要的bug,也推荐使用const,和let;
const是声明一个常量所用的关键字;
let是声明一个可变变量的关键字。
const let怎么使用?
const和let的使用方式和var基本一致,需要注意的是:
const在使用时,声明了就必须赋值,且不可以更改这个变量
function fun(){
let a
a = 2
const b = 2
b = 3 //ERROR 不能这样使用,不能修改他的赋值
const c //ERROR 不能这样使用,必须在声明是紧跟着赋值
c = 2
const d = {a:1,b:2}
d = {a:2} //ERROR 不能修改他的赋值
d.a = 2 //允许修改其属性中的值
}
临时死区
js运行的时候,会提前扫描代码中的声明语句,将var声明提升到作用域顶部,而将const和let声明放入临时死区中,只有遇到声明变量的语句中时,才将变量从临时死区中移除,当代码访问临时死区中的变量时会抛错
function fun(){
console.log(a) //会报错'a' is not defined no-unde
let a = 3
if(true){
let a = 2
console.log(a) //2
}
console.log(a) //3
}
因为js的变量提升机制,将所有变量的声明提升到作用域顶级,所以可能存在相同的变量,如果没有重复声明,那么这里就会报错。所以当遇到重复声明时,编译器会自动忽略声明,直接赋值。
块级作用域
const,let增加了块级作用域,去除了变量提升机制,所以就不能重复声明
块级作用域就是在js中包含在{...}中语句。
为什么会出现块级作用域?
块级作用域就是为了避免使用var声明变量后,此变量就可在全局使用,或者改变了全局变量中不想改变的值。有了块级作用域就可以声明变量只在此作用域中起作用,不影响其他作用域的值。
并且可以更好的施行垃圾回收,到执行走出作用域后,就已经判定此作用域的对象不可用了
什么情况下会形成块级作用域?
块级作用就是使用类似if(condition){} while(condition){} 如此就形成了块级作用域
总结:var const let 区别
1. const,let不可以在同一scope中重复声明同一个变量;var可以
2. const,let在的不同作用域重新声明的重复变量,只影响当前作用域,不影响全局变量;var要修改全局变量的值
3. const声明的值不可以重新赋值;let和var可以