为什么将一个类错误地挂在另一个类构造函数中

问题描述

我定义一个类Node,然后定义一个类LinkedList,在LinkedList构造函数内部,我创建一个新的Node。问题是,如果我同时运行两个声明,那么即使在Nodeed声明在LinkedList之前定义了第二次运行声明,我也会收到错误消息:初始化前无法访问Node

class Node {}

class LinkedList {
  constructor() {
    console.log(new Node());
  }
}

new LinkedList()

请注意,仅当代码块一次运行时才会发生,并且第二次在Google chrome开发工具中运行时会发生这种情况,并且将Node重命名函数也可以解决此问题。我认为这与吊装有关,但是我想了解为什么会发生吊装以及如何吊装。

更新: 对于那些说一次运行所有块是什么意思,或者说它不可复制,这是我如何一次运行整个块以及它如何失败的表象。

enter image description here

环境信息: Google Chrome 80.0.3987.122(正式版)(64位) 修订版cf72c4c4f7db75bc3da689cd76513962d31c7b52-refs / branch-heads / 3987 @ {#943} 操作系统Linux JavaScript V8 8.0.426.25

解决方法

TL; DR

不要在devtools控制台中测试非平凡的代码。这是一个非常不寻常的环境,可能会引起误解。而是在实际的模块/脚本(在系统文件中,在诸如CodePen或CodeSandbox或jsFiddle之类的工具中)中测试代码

更多详细信息

我无法复制您在我的Chrome或Firefox版本中看到的行为; Chrome使您可以重新声明这些常量,而Firefox则抱怨它们已被声明,如果您实际拥有这些常量,将会得到

class Node { }

class Node { }

在编译单元(通常是“文件”或模块)中。在相同作用域中具有两个具有相同标识符名称的class声明是错误的,而在相同作用域中具有两个具有相同标识符名称的函数声明不是(最后一个获胜),这大概可以说明以下事实:当您将它们转换为函数时,您没有看到它。

某些浏览器控制台可能会让您逃脱它,只需违反规则,或者在每次发布代码时都创建嵌套的匿名作用域,因此最终成为:

class Node { }

{
    class Node { }
}

,如果您第三次做class Node { }

class Node { }

{
    class Node { }

    {
        class Node { }
    }
}

以此类推。

但这是游戏机的怪异之处。同样,这也是为什么最好不要在devtools控制台中测试非平凡代码的原因。