1. 变量提升
console.log(a) // undefined
var a = 1
console.log(b) // 报错
let b = 1
console.log(c) // 报错
const c = 1
var定义的变量存在变量提升,而const和let定义的变量不存在变量提升
这里var定义的变量为何会被提升呢?
因为JS代码片段执行之前都会被预编译,预编译过程非常短暂,在预编译过程中,JS会搜集所有变量提前声明,等到具体执行的时候才会去执行某个代码片段,这就是变量提升的本质
上面代码实际是这样预编译的:
var a;
console.log(a)
a = 1
这边var定义的变量会被提升到前面去声明,所以这边输出的a才会是undefined
用let/const声明的变量在声明之前输出会报错,这里是因为let和const声明的变量是绑定在这个块级作用域上,不能提升变量,并且存在暂时性死区,那么什么是暂时性死区呢?
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
2. 作用域限制
{
var a = 1
}
console.log(a) // 1
{
let b = 1
}
console.log(b) // 报错
{
const c = 1
}
console.log(c) // 报错
let和const会受到作用域限制,在作用域外部是无法访问作用域内部的值;而var定义的变量不受作用域限制,属于全局作用域,在作用域外部也是可以访问到内部的变量
3. 重复声明
var a = 1;
console.log(a) // 1
var a = 2;
console.log(a) // 2
var声明的变量可以重复声明
let a = 1;
console.log(a)
let a = 2;
console.log(a)
// 报错
let在同一个作用域中,变量不能重复声明,会报错
4.const声明常量
const和let特点基本上是一致的,他们唯一不同的是,const声明的是常量,一旦声明了,就得初始化,后面也不能修改当前值,否则会报错
const a = 1;
a = 2;
// 报错,const声明的变量不能修改
const b;
// 报错,const声明的变量必须得带初始值
这里有一点需要注意,const声明的对象可以修改属性值,但是不能更改它的引用,如下代码:
const a = {};
a.b = 1;
console.log(a) // {b:1}
以上代码中,这里const声明的变量是个对象,所以就可以修改内部的属性值
const a = {};
a = { b: 1 }
console.log(a) // 报错
上面代码中, 直接修改a的整个对象引用值就不可以了
5. 总结
- var存在变量提升,let和const没有
- var可以重复声明变量,而let和const不能
- var在作用域内部定义的变量,在作用域外部也可以访问到,而const和let不行
- var可以脱离当前作用域,相当于属于全局变量,而const和let属于块级作用域,只能在当前作用域中才可以访问到
- const定义的变量不能修改,并且初始化一定要赋值,否则会报错