JavaScript-暂时性死区

262 阅读2分钟

前言

ES6新增了let和const这两种声明变量的方式,在我们学习的时候可能会偶尔遇到暂时性死区这个概念,很多同学可能看到这个奇怪的名词就直接选择了暂时性忽略,以后再来深入理解,直到面试官问到后才后悔莫及,然后就寄了

变量提升

学过js都知道var声明变量会发生变量提升,也就是变量会被提升到全局作用域或者函数作用域的顶部,其实let和const在声明变量时也会发生变量提升,我们直接看代码

function foo() {
  debugger
  console.log('进行一些操作')
  var a = 1
  let b = 2
  const c = 3
}

foo()

打开控制台看到调试结果如下图

截屏2022-04-30 14.39.19.png 这足以证明let和const声明的变量也是会发生变量提升的

暂时性死区

那么问题来了,var和let,const的变量提升有什么不同呢?先看下面的代码

function foo() {
  debugger
  console.log(a)
  console.log(b)

  var a = 1
  let b = 2
}

foo()

截屏2022-04-30 15.12.49.png 在访问a时返回了undefined,但是访问b时控制台给出了报错,那么前面在调试时明明看到a,b的值都是undefined,为什么b不可以访问呢?

这就是由于暂时性死区的存在,我们不能在声明之前使用let和const变量,必须要等到变量被初始化后才能访问,所以虽然var,let,const都会发生变量提升,但是var和后两者还是有不同的

同样的,下面的代码执行也会报错,控制台提示不能在a被初始化之前访问a

let a = 1
function foo() {
  a = 1
  let a = 1
}

foo()

很多同学这时候会满脑子问号,不是有全局变量a了吗,为什么不会去访问全局的a,我们直接debugger

let a = 1
function foo() {
  debugger
  a = 1
  let a = 1
}

foo()

截屏2022-04-30 15.47.17.png 这里在执行foo时执行上下文中的变量对象初始化变量时是使用的函数内的a,而不是全局的a,所以,同样由于暂时性死区的存在,在初始化a之前访问它会报错

总结

暂时性死区的存在使得let和const的变量声明语法相比于原来的var更加严格,相比于var声明变量,let和const还支持块级作用域,阻止同一作用域变量重复声明特性

参考文献

  1. JavaScript高级程序设计