声明变量和定义变量有区别吗

IT技术 javascript variables
2021-01-12 21:57:55

我尝试在控制台中一一写下以下几行

let x = y //throws error "Uncaught ReferenceError: y is not defined"
console.log(x) //throws error "ReferenceError: x is not defined"
let x = 3; //gives error "Uncaught SyntaxError: Identifier 'x' has already been declared"
x = 3 //ReferenceError: x is not defined

现在的问题是,一个变量怎么可能没有定义并且同时被声明两者有什么区别吗。

1个回答

A letorconst变量只能声明一次 - 也就是说,当您let <variableName>在一个范围内时,您已经<variableName>在该范围内声明,并且不能在该范围内再次声明它。

先前链接的问题

有赋值时,首先解析右边;如果右侧抛出错误,它永远不会到达左侧,并且用 let 声明的变量永远不会被正确初始化;它将永远留在非军事区/时间死区

您不能重新声明已经声明的变量,即使在初始化期间尝试赋值时抛出了错误。

但是在第 4 行,x=3 应该进行适当的分配,并且应该从 TDZ 中删除 x。但这也失败了。我不明白

变量初始化(例如,let x运行)后,可以将其分配给。但就像你不能分配给一个变量之前它的let初始化,你也不能分配给一个变量后,当它的初始化没有成功完成:

x = 'foo';
let x = 'bar';

错误:

未捕获的 ReferenceError:x 未定义

这与您尝试时在控制台中发生的事情相同:

let x = y
// Uncaught ReferenceError: y is not defined
// x has not been initialized, so the next line throws:
x = 'foo'
// Uncaught ReferenceError: x is not defined

x 仍然没有被初始化,所以错误是一样的。

不过,遇到这种事情很奇怪- 您只能在控制台中看到它。在普通脚本中,抛出的错误将阻止进一步执行,并且变量名称永远未初始化的事实无需担心。


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

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

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

在此处输入图片说明

我想指出,在 Firefox 的控制台中let x = y确实会初始化x并且x = "foo"不会抛出。然而,在控制台之外做同样的事情,它会正确抛出。
2021-03-22 21:57:55