1.let
1)它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。
{
let a = 1;
var b = 2;
}
a // ReferenceError: a is not defined.
b // 2
for
循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
for (let i = 0; i < 2; i++) {
let i = '123';
console.log(i);
}
// 123
// 123
2)不存在变量提升 *
var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined
。
let
命令所声明的变量一定要在声明后使用,否则报错。
// var 的情况
console.log(a); // 输出undefined
var a = 2;
// let 的情况
console.log(b); // 报错ReferenceError
let b= 2;
3)暂时性死区 *
在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
if (true) {
// TDZ开始
a = 'abc'; // ReferenceError
console.log(a); // ReferenceError
let a; // TDZ结束
console.log(a); // undefined
tmp = a;
console.log(a); // 123
}
4)不允许重复声明 *
let
不允许在相同作用域内,重复声明同一个变量。
// 报错
function fn() {
let a = 1;
var a = 2;
}
fn()
// 报错
function fn() {
let a = 1;
let a = 2;
}
fn()
不能在函数内部重新声明参数。
function func(arg) {
let arg;
}
func() // 报错
function func(arg) {
{
let arg;
}
}
func() // 不报错
5)块级作用域
内层作用域可以定义外层作用域的同名变量。
{
let a = 'Hello';
{let a= 'World'}
};
2. const
同let一样,const
也有以下几个特点
- 块级作用域
- 不允许重复声明
- 暂时性死区
- 不存在变量提升
唯一不同的是
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
const A= 1;
A //1
A = 2;
// TypeError: Assignment to constant variable.
const
一旦声明变量,就必须立即初始化,不能留到以后赋值。只声明不赋值,就会报错。
const a;
// SyntaxError: Missing initializer in const declaration
const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。
const a= {};
// 为 a 添加一个属性,可以成功
a.prop = 123;
a.prop // 123
// 将 a指向另一个对象,就会报错
a= {}; // TypeError: "a" is read-only