Javascript 是什么导致了“之间”的不同行为;var";及;让我们;当为它们分配一个抛出错误的函数的返回值时

Javascript 是什么导致了“之间”的不同行为;var";及;让我们;当为它们分配一个抛出错误的函数的返回值时,javascript,var,throw,let,Javascript,Var,Throw,Let,请在下图中找到代码。 1.将实际抛出错误的函数的返回值赋给使用关键字“let”声明的变量“withLet”。 2.调用“withLet”,出现错误:“withLet未定义”。 3.尝试使用'let'断言'withLet',错误显示'withLet'已经声明 但“var”并不存在悖论(请在下图中找到) 我很好奇是什么导致了这两种情况之间的不同行为。“未定义”和“已声明”描述同一个变量,这一点非常明确 let withLet = (function() {throw 'error!'})() var

请在下图中找到代码。 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"
let-withLet=(函数(){throw'error!'})()
var withVar=(函数(){throw'error!'})()
//VM2470:1未捕获错误!
//(匿名)@VM2470:1
//(匿名)@VM2470:1
维莱特
//VM2484:1未捕获引用错误:未在上定义withLet
//:1:1
//(匿名)@VM2484:1
withVar
//未定义
let withLet=‘某物’
//VM2520:1未捕获的语法错误:标识符“withLet”已被删除
//宣布
//时间:1:1
//(匿名)@VM2520:1
withVar='sth'
//“某物”
截图:


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

由解释器解析为

var withVar;
withVar = (function() {throw 'error!'})()
对于
let
-
let
变量,当
let\uu
行运行时,情况就不同了。当有赋值时,首先解析右侧;如果右侧抛出错误,它永远不会到达左侧,并且用
let
声明的变量永远不会正确初始化;它将永远保留在中,因此尝试重新分配它会抛出一个错误

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


以上是早期Chrome版本中的一个问题。但是,现在允许重新声明
let
,所以

未捕获的语法错误:已声明标识符“withLet”

无论之前的变量初始化是否成功,都不应再发生:


Firefox只打印
未定义的
。Chrome会抛出
错误对于每个函数,calli认为这是引擎中的一个bug
withLet
应该初始化并且
未定义
,但是由于变量作用域的性质,它可能会以不同的方式处理它。这里有重要的说明-这发生在Chrome/V8中,而不是在Firefox中。所以,这是特定于实现的行为。只需稍微扩展一下,变量有三个阶段才能变为“实”。声明(标识符存在)、初始化(idientifier处于活动状态并且可以使用)、赋值(为该标识符分配了一个值)。对于
var
声明+初始化被挂起。对于
let
/
const
而言,只有声明被挂起,初始化将在稍后进行-如上所述,当到达
let myVar
行时。
var withVar;
withVar = (function() {throw 'error!'})()