let特性
基本使用方法:
\
1.不存在变量提升
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
\
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
2.暂时性死去
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
在代码块内,使用let命令声明变量之前,该变量都是不可用的。在语法上称为"暂时性死区"
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。
typeof x; // ReferenceError
let x;
如果一个变量根本没有被声明,使用typeof反而不会报错。
typeof undeclared_variable // "undefined"
一些隐蔽的或者不易被察觉的"暂时性死区":
function bar(x = y, y = 2) {
return [x, y];
}
bar(); // 报错
\
// 不报错
var x = x;
\
// 报错
let x = x;
// ReferenceError: x is not defined
\
3.let不允许在相同作用域内,重复声明同一个变量。
// 报错
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() // 不报错
\
2.块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
\
第一种场景,内层变量可能会覆盖外层变量。
var tmp = new Date();
\
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
\
f(); // undefined
由于存在变量提升,导致内层的tmp变量覆盖了外层的的tmp变量
\
第二种场景,用来计数的循环变量泄露为全局变量。
var s = 'hello';
\
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
变量i只用来控制循环,但是循环结束后,并没有消失,泄露成了全局变量