let 语句声明一个块级作用域 的本地变量
let x = 1;
if (x === 1) {
let x = 2;
console.log(x);//输出2
}
console.log(x);//输出1
let声明的变量只在其声明的块或子块中可用,与var的区别在于var声明的变量的作用域是整个封闭函数。
function varTest() {
var x = 1;
{
var x = 2; // 同样的变量x, x的作用域是这个函数空间
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
{
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}
function letTest() {
var x = 1;
{
let x = 2; // x 的作用域就是这个块{}
console.log(x); // 2
}
console.log(x); // 1
}
- 在第一个函数内,因为x都是var声明的,那么x的作用域就是这个封闭函数内,第二次赋值会替代第一次,所以都输出了2
- 在第二个函数内,因为x都是let声明的,x的作用域就是其声明的块或者子块,第一个x的作用域是函数及其内部块{},第二个x在子块里面声明,其作用域就是该子块内部
- 第三个函数与第一个对比可得到,let仅仅是作用在该子块中,函数体内的x变量是由var声明的
位于函数或代码顶部的var声明会给全局对象新增属性, 而let不会
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
此时这个this指向的是windows,关于this更多的内容可以查询相关资料
暂存死区
与通过 var 声明的有初始化值 undefined 的变量不同,通过 let 声明的变量直到它们的定义被执行时才初始化。在变量初始化前访问该变量会导致 ReferenceError。该变量处在一个自块顶部到初始化处理的“暂存死区”中。
console.log(x); // undefine
console.log(y); // "error" "ReferenceError: Cannot access 'y' before initialization
var x = 1;
let y = 2;
console.log(x); // undefined
var x = 1;
let y;
console.log(y); // undefined
通过var声明的变量,在其定义变量时已经做了初始化,而let声明的变量,到它们的定义被执行时才初始化。可以看两个代码块的区别,let声明变量时,如果引用在声明之前,就会报一个错误ReferenceError。