目录
一、let
1、let 都是块级局部变量
顾名思义,就是只在当前代码块起作用
- 作用域只在他所在的代码块
- 一个 {}可以看作一个作用域
- if语句和 for语句里面的{ }也属于块作用域
for (let i = 0; i < 3; i++){
console.log(i); //0 1 2
}
console.log(i); //i is not defined
2、let不存在变量提升
var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined
。这种现象多多少少
是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
//变量提升
console.log(a); //undefined a已经声明,但未赋值,得到undefined
var a = 1;
console.log(b); //error b is not defined
let b = 2;
3、let 不允许重复声明
let 不允许在相同的作用域内,重复声明同一个变量。
因为函数的形参在栈中会被解析成函数的私有变量出现在其执行上下文中,let不允许重复定义。
let a = 11;
let a = 22;
console.log(a); //Identifier 'a' has already been declared
4、暂时性死区TDZ
- TDZ又称暂时性死区,意思是变量在作用域内已经存在,必须在 let / const声明后面使用
- ES6明确规定,如果区块中存在let/const命令,这个区块用这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用的变量,就会报错
- TDZ本质:只要一进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
- TDZ能够让开发者养成先声明后使用的习惯,让程序更加的稳定。
var num = 10;
if (true) {
console.log(num);
let num = 20; //报错,let关键字声明,具有暂时性死区特性
}
二、const
1、const 声明一个只读的常量
- 一旦声明,常量值就不可以改变。所以const一旦声明就必须立即初始化。
- 只声明,不赋值,会报错(注意:var let 只声明不赋值 : undefined)
//const 声明类型的值不可修改
const a = 10;
a = 20;
console.log(a); //Assignment to constant variable.
//const 只声明,不赋值,会报错
const b; //Missing initializer in const declaration
2、不能重新赋值const定义的值
但是可以修改const’声明的对象类型。
const arr = [100, 1001];
arr[0] = 123;
console.log(arr); // [123,1001]
arr = [1, 2]; // 不能更改
console.log(arr); //Assignment to constant variable.
为什么const声明的基本类型变量不能被修改,而复杂类型变量就可以?
因为 const 保存的是指向数组或对象的指针。对于基本类型值,使用const声明的变量是不可以被修改的。但是对于对象,指针依然不能被修改,但是指针指向内容可以修改
- const 的作用域与let命令相同,只在声明所在的块级作用域内有效
- const声明的变量也不存在变量提升,同样存在暂时性死区,只能在声明位置的后面使用
- const声明的常量和let一样不可重复声明
三、三者区别
1. 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象。
2. 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
3. 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值。
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |