1.作用域
- var 没有块级作用域,而 let 声明的范围是块作用域; 一对大括号 就是 一个块级作用域
if (true) {
var msg = "hello";
console.log(msg);
}
console.log(msg);
if (true) {
let msg = "hello";
console.log(msg);
}
console.log(msg);
if (true) {
let msg;
let msg;
}
- JS 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,这是因为同一个块中没有重复声明:
let msg = 666
console.log(msg)
if (true) {
let msg = '啊哈哈'
console.log(msg)
}
- var 和 let 声明的并不是不同类型的变量,它们只是指出变量在相关作用域如何存在,所以对声明冗余报错不会因混用 var 和 let 而受影响:
var msg;
let msg;
let msg;
var msg;
2.变量提升
//用var命名的变量有变量提升
console.log(num1)
var num1 = 10
// 以上代码运行时,相当于下面的写法
var num2
console.log(num2)
num2 = 10
/*****************************************/
//用 let 或 const 命名的变量没有变量提升
console.log(num3)
let num3 = 10
console.log(num4)
const num4 = 10
3.暂时性死区
-
在代码块内,使用let和const命令声明变量之前,该变量都是不可用的,叫暂时性死区
var tmp = 123
if (true) {
tmp = 'abc'
let tmp
}
- 暂时性死区和不能变量提升的意义在于: 为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
4.重复声明同名变量 和 重新赋值
//var 关键字可以声明同名变量,实际第二次声明是对第一次声明的变量重新赋值
var num1 = 10
var num1 = 20
console.log(num1)
//let 和const 关键字不能重复声明同名变量,即使之前是用var声明的也会报错
var num2 = 10
let num2 = 20
//let 和 var 在声明变量时,可以不用初始化
let num3
console.log(num3)
var num4
console.log(num4)
//const 声明常量时必须初始化,因为 `const` 关键字声明的是常量,声明后不能再赋值
const num5
//let 声明的变量可以重新赋值
let num1 = 10
num1 = 20
console.log(num1)
//const 只能在声明时赋值,之后不能再重新赋值
const num2 = 10
num2 = 20
5.var全局变量变成windows对象
var a = 666
console.log(window.a)
let b = 666
console.log(window.b)
const c = 666
console.log(window.c)
6.总结
- var 声明的范围是函数作用域,let 和 const 声明的范围是块作用域
- var 声明的变量会被提升到函数作用域的顶部,let 和 const 声明的变量不存在提升,且具有暂时性死区特征
- var 允许在同一个作用域中重复声明同一个变量,let 和 const 不允许
- const 的行为与 let 基本相同,唯一 一个重要的区别是,使用 const 声明的变量必须进行初始化,且不能被修改
- 在全局作用域中使用 var 声明的变量会成为 window 对象的属性,let 和 const 声明的变量则不会