如何让提升工作扩展 类?

How to get hoisting to work for extended classes?

我说的是:

class MyAction {
}
class MyActionEdit extends MyActionNew { // <-- error pointing here
}
class MyActionNew extends MyAction {
}

我收到以下错误:Uncaught ReferenceError: Cannot access 'MyActionNew' before initialization.

我不是在加载所有 js 之前创建实例。所以我不明白,为什么吊装在这里不起作用。问题是:我无法更改 class 定义的顺序(它们从各种文件加载并组合成一个大脚本 - 在本例中为 3 个组合文件)。

我已经阅读了这个问题和许多其他问题,但是 none 确实回答了我的问题。

这里的例子是:

class MyAction {
}
let test: MyActionNew = new MyActionNew(); // <- Hoisting works here
class MyActionEdit extends MyAction {
}
class MyActionNew extends MyAction {
}

我该如何处理?我不知道这是否有帮助,但我正在使用打字稿生成 javascript 文件。可能有什么东西?

相关:

我已经在 Whosebug 上阅读了所有带有标签“提升”的问题,但没有找到答案。

JavaScript类没有吊装。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

In the related link is an example with the Hero class. There are many answer here in Whosebug, that are telling, that classes are hoisted and that this behaviour changed between ES5 and ES6. Take a look at this answer:

是但不是。 class 名字 提升是正确的。但是,这与您的情况无关。

Javascript分两步执行:

  1. Parsing/compilation
  2. 运行时间

在解析步骤中,Javascript 引擎将您的代码分解、读取、标记化,然后通常将其转换为可执行形式。在此步骤中,它列出了将在运行时使用的一般结构,其中包括事物的 名称 以及它们所属的范围。因此,name MyActionEdit 将在正确的范围内创建。这就是提升。因为在第二步,运行时,当代码真正运行时,那个名字已经存在了,即使它在作用域后面出现:

console.log(foo);

var foo = 'bar';

执行方式如下:

  1. 解析 var foo 并创建一个保留该名称的作用域。
  2. 运行时:执行console.log(foo)然后执行foo = 'bar'

这就是为什么这个 不会 引发错误并记录 undefined 的原因。这就是“吊装”。

现在,classes 也在解析期间完整定义。 解析步骤 创建了 classes。如果该解析步骤成功,则 classes 已经“提升”并在运行时可用。*但这无关紧要,因为在解析期间声明的顺序是错误的,并且 Javascript 不能 extend 尚未声明的 class。它必须忽略第一个 class 声明,跳到下一个,然后重复解析过程以声明先前跳过的声明。这可能会导致无限循环,而且通常效率极低。或者,如果它可以先“提升”classes,那么它们应该以什么顺序被提升?!引擎应该如何知道按照它们需要的顺序提升 class 声明以使声明具有逻辑意义?

您可以按正确的顺序声明 classes。

* 除非它们在声明之前不可访问,因为这种提升行为被认为是令人困惑的,并且被 明确禁止。