当为它们分配抛出错误的函数的返回值时,导致"var"和"let"之间的不同行为的原因

Hey*_*eyi 3 javascript var let throw

请在下图中找到代码.1.将函数的返回值(实际上抛出一个错误)分配给使用关键字"let"声明的变量'withLet'.2.调用'withLet',发生错误:'withLet未定义'.3.尝试使用'let'断言'withLet',错误显示已经声明'withLet'.

但是'var'不存在悖论(请参见下图).

我很好奇是什么导致了这两种情况之间的不同行为.它是非常有线的,"未定义","已经声明"描述了一个相同的变量.

let withLet = (function() {throw 'error!'})()
var withVar = (function() {throw 'error!'})()
//VM2470:1 Uncaught error!
//(anonymous) @ VM2470:1
//(anonymous) @ VM2470:1
withLet
//VM2484:1 Uncaught ReferenceError: withLet is not defined at 
//<anonymous>:1:1
//(anonymous) @ VM2484:1
withVar
//undefined
let withLet = 'sth'
//VM2520:1 Uncaught SyntaxError: Identifier 'withLet' has already been 
//declared
//at <anonymous>:1:1
//(anonymous) @ VM2520:1
withVar = 'sth'
//"sth"
Run Code Online (Sandbox Code Playgroud)

截图:

Cer*_*nce 10

var变量声明被提升 - 变量名称初始化被提升到包含函数的顶部(或者,如果没有函数,则被提升到外部块的顶部).所以

var withVar = (function() {throw 'error!'})()
Run Code Online (Sandbox Code Playgroud)

由解释器解析为

var withVar;
withVar = (function() {throw 'error!'})()
Run Code Online (Sandbox Code Playgroud)

同样的情况并非如此let- let一旦let __线路运行,变量就会被初始化.在分配时,首先解析右侧; 如果右侧抛出错误,它永远不会到达左侧,并且声明的变量let永远不会被正确初始化; 它将永远留在非军事区/时间死区,所以试图重新分配它会引发错误.

这有点奇怪,因为代码是在控制台中运行的- 通常,JS在<script>标记内运行,如果发生这样的错误,通常不再运行代码,并且声明的变量let不再可重新分配的事实是最不用担心.

  • 只是为了扩展一点 - 变量有三个阶段变成"真实".声明(该标识符存在),初始化(idientifier是活动的并且可以使用),赋值(赋值给该标识符).对于`var`,声明+初始化被提升.对于`let` /`const`,只有*声明*被提升,*初始化*稍后 - 如所述,当达到'let myVar`行时. (3认同)