- 块级作用域
- 不存在变量提升
- 暂时性死区
- 不允许重复声明
1. 块级作用域
let 命令,用来声明变量,但声明的变量,只在 let 命令所在的代码块有效。
{ let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1
2. 不存在变量提升
var
命令会发生“变量提升”现象,即变量可以在声明之前使用,值为 undefined
。
这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
为了纠正这种现象,let
命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
// var 的情况 console.log(foo); // 输出undefined var foo = 2; // let 的情况 console.log(bar); // 报错ReferenceError let bar = 2;
3. 暂时性死区(temporal dead zone,简称 TDZ)
只要块级作用域内存在 let
命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
“暂时性死区”也意味着 typeof
不再是一个百分之百安全的操作。
typeof x; // ReferenceError let x;
作为比较,如果一个变量根本没有被声明,使用 typeof
反而不会报错。
typeof undeclared_variable // "undefined"
“暂时性死区”报错的例子
// 示例一 function bar(x = 2, y = x) { return [x, y]; } bar(); // [2, 2] // 示例二 // 不报错 var x = x; // 报错 let x = x; // ReferenceError: x is not defined
4. 不允许重复声明
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; }
因此,不能在函数内部重新声明参数。
function func(arg) { let arg; } func() // 报错 function func(arg) { { let arg; } } func() // 不报错