let声明变量那些事

207 阅读2分钟

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。