javascript - 变量错误,未使用 let 正确初始化

标签 javascript ecmascript-6

我对 JS 中的 Set 类型感到困惑。如果您使用未正确初始化的 Set 创建变量,则无法再使用它(作为 Set 或原始类型)。 在控制台中尝试:

let someSet = new Set(4);
/* Uncaught TypeError: number 4 is not iterable (cannot read property Symbol(Symbol.iterator))
    at new Set (<anonymous>)*/

someSet
// Uncaught ReferenceError: someSet is not defined 

let someSet = new Set([4])
// Uncaught SyntaxError: Identifier 'someSet' has already been declared
someSet
// Uncaught ReferenceError: someSet is not defined

let someSet = 'ho-ho-ho'
// Uncaught SyntaxError: Identifier 'someSet' has already been declared

someSet = 'ho-ho-ho'
// Uncaught ReferenceError: someSet is not defined

你能解释一下为什么吗? 查看屏幕:

enter image description here

最佳答案

这几乎只能在控制台上发生,因为在实际代码中,如果 let someSet = new Set(4);new Set 部分失败,该错误会将您带出 let someSet 所在的范围,因此不会出现此问题。

交互式控制台(例如浏览器中的控制台)必须玩一些具有范围的游戏等。您最终得到了一个已声明但未初始化的变量(已准备好使用);它永远处于暂时死区 (TDZ),因为规范的 InitializeBinding从未对其执行过操作。 (变量是环境对象中的“绑定(bind)”[还有其他类型的绑定(bind)]。)与 var 创建的变量绑定(bind)不同,由 let 创建的变量绑定(bind)可以未初始化。这是一个例子:

{
    // `x` is *declared* upon entry to this scope, but not *initialized* yet
    x = 5; // Fails because the `x` binding isn't initialized yet
    let x;
}

同样,您的确切示例只能在像 Chrome 控制台这样的控制台中出现。如果 new Set(4) 没有抛出错误,则 let someSet = new Set(4); 行将按以下顺序执行这些操作:

  1. 声明(但不初始化)变量(绑定(bind))someSet
  2. 评估初始化器new Set(4)
  3. 使用 #2 的结果值来初始化变量

问题是,由于 new Set(4) 抛出错误,因此第 3 步从未发生。在正常环境中,该错误会将您带出声明 someSet 的范围,但不会在 Chrome 控制台中出现。结果,你根本无法使用 someSet,因为你无法再次声明它(它已经被声明过),并且你无法读取它的值(它没有一个,它是未初始化的),并且您无法向其写入值(因为执行此操作的操作 SetMutableBinding 检查变量是否已初始化,如果未初始化则失败 - 因为这就是 TDZ 的工作原理)。

关于javascript - 变量错误,未使用 let 正确初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56238998/

相关文章:

javascript - 如何通过 Webpack 导入和使用 bootstrap-vue

javascript - 如何强制路由器更新 Angular 2 中的当前路由?

javascript - 调用按钮单击功能时保持类 this

javascript - 检查值是否是 JavaScript 中的符号

javascript - 使用 prefers-reduced-motion 禁用动画

javascript - 为什么内容要写成文本?

javascript - Flot JS 折线图 按不同属性排序

javascript - 如何停止 datetimepicker 默认情况下在文本框中设置今天的日期 onclick

javascript - 如何将下拉选项值附加为数组

javascript - CJS 和 ES6 模块之间的语法差异