【问题标题】:Is there any difference between declared and defined variable声明变量和定义变量之间有什么区别
【发布时间】:2019-07-25 13:38:48
【问题描述】:

我尝试在控制台中逐行编写以下行

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

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

【问题讨论】:

  • 浏览器控制台对语言的使用不当。那些ReferenceErrors 真的应该说这个变量不是“声明的”,但是一直都是这样。
  • 来自链接:有赋值时,先解析右边;如果右侧抛出错误,它永远不会到达左侧,并且用 let 声明的变量永远不会被正确初始化;它将永远停留在非军事区/临时死区(并且您不能重新声明已声明的变量,即使在初始化期间尝试的赋值引发了错误)。
  • 声明初始化有很大区别。在您的第一行x = y 中,您声明了x 并尝试将y 分配给它,即undefined,因此声明了x,并将使用undefined 初始化为value。这就是你得到x 的原因。
  • @MaheerAli let x = 3; 将抛出错误,因为您已经声明了它。但是x=3 不应该抛出错误,除非你将它定义为const
  • 被声明并不意味着它将被初始化为未定义。 Are variables declared with let or const not hoisted in ES6?

标签: javascript variables


【解决方案1】:

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

来自previously linked question

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

您无法重新声明已声明的变量,即使在初始化期间尝试的赋值引发了错误。

但是在第 4 行,x=3 应该进行正确的分配,并且应该从 TDZ 中删除 x。但这也失败了。我没看懂

在变量被初始化之后(例如,let x 运行),它可以被赋值。但是就像您不能在其let 初始化之前分配给一个变量一样,您也不能在其初始化未成功完成时分配给一个变量:

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

错误:

未捕获的rigencerError: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版本中的问题。但是in Chrome 80+,现在允许重新声明let,所以the error

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

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

【讨论】:

  • 我想指出,在 Firefox 的控制台中 let x = y 确实初始化了 x 并且 x = "foo" 不会抛出。但是做同样的out of the console,它会正确抛出。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 2015-07-09
  • 2012-07-08
  • 2017-11-10
  • 2015-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多