引言:var是ES5,let和const是ES6的命令,都是用于变量的声明,那它们又有什么不同呢?
一、作用域
-
var 的作用域是函数作用域
-
let和const的作用域是块作用域,在哪里声明就只能在哪里访问
-
块作用域的优点:防止内层变量覆盖外层变量;分割代码成块不相互影响;
-
块作用域的缺点:在
代码块中使用函数声明的方式创建函数可能会产生一些问题,所以在块中使用匿名函数的形式
// 作用域
var a = 1;
{
var a = 2;
console.log(a, '1'); // 2 "1"
}
// 函数作用域,内层变量会覆盖外层变量
console.log(a, '2'); // 2 "2"
let b = 3;
{
// 块作用域
let b = 4;
console.log(b, '3'); // 4 "3"
}
console.log(b, '4'); // 3 "4"
二、变量提升
同一作用域中,在变量声明之前时候可以被访问和使用,但是值是undefined
- var声明的变量存在变量提升的现象
- let和const没有变量提升
// 变量提升
console.log(a, '1'); // undefined '1'
// console.log(b, '2'); // ReferenceError: Cannot access 'b' before initialization
var a = 1;
let b = 2;
!!!暂时性死区:进入到当前作用域时,所使用的变量就已经存在了,但是不可获取,只有到声明的那一行代码执行完毕后才可以获取和使用!!! 暂时性死区和不能变量提升的意义在于: 为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
三、重复声明变量
var可以在相同作用域中重复声明同一个变量,而let和const则不可以,包括由其他声明关键字声明的变量
四、挂载到顶层对象(浏览器的window和node的global)
- var 声明的全局变量会挂载到顶层对象下
- let、const声明的全局变量不会挂在顶层对象下面
五、const的特殊之处
-
var和let在声明的时候可以不赋值;
-
const在声明的同时必须要赋值,否则就会报错
-
const声明的基础数据类型的变量不能修改,而引用类型的数据不可以修改指针的地址值,只能修改内部的属性
-
var和let没有这个限制