【问题标题】:How to get hoisting to work for extended classes?如何让提升为扩展课程工作?
【发布时间】:2020-09-11 06:45:58
【问题描述】:

我说的是:

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

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

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

我已经阅读了这个问题和许多其他问题,但没有人回答我的问题。

这在这里工作例如:

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

我该如何处理?我不知道这是否有帮助,但我正在使用打字稿来生成 javascript 文件。会不会有事?

相关: Typescript class: will class be hoisted when I use two classes?

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

【问题讨论】:

  • 向上扩展MyActionNew,向下扩展MyAction,其中的女巫现在是正确的
  • Javascript 分两步执行:1) 解析/编译,2) 运行时。提升是有效的,因为变量名等某些东西是在解析步骤中创建的,因此在运行时已经存在。但是您想要的一切都发生在解析步骤中,并且在该步骤中,顺序必须是合乎逻辑的;那里没有吊装。
  • 简而言之 - why hoisting is not working here - 因为类定义没有被提升
  • @Thomas 这里没有循环扩展。只是MyActionMyActionNewMyActionEdit。只是声明的顺序搞砸了。

标签: javascript typescript hoisting


【解决方案1】:

在相关链接中是 Hero 类的示例。 stackoverflow 中有很多答案,说明类被提升了,并且这种行为在 ES5 和 ES6 之间发生了变化。看看这个答案:Why are ES6 classes not hoisted?

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

Javascript 分两步执行:

  1. 解析/编译
  2. 运行时

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

console.log(foo);

var foo = 'bar';

执行如下:

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

这就是为什么这个不会引发错误以及为什么它会记录undefined。这就是“吊装”。

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

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

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

【讨论】:

  • 好吧,可悲的是,这对我来说是有道理的。所以我必须改变我的文件收集器来管理连接文件的正确顺序。谢谢你的澄清。我已经接受了你的回答。
【解决方案2】:

【讨论】:

  • 我已经读过了。但这似乎只适用于 class 关键字。当我使用打字稿时,我可以将类输出为任何其他格式。但是我不明白,如果有声明,吊装在哪里可以工作。在我发布我的问题之前,我已经花了几个小时谷歌搜索和阅读堆栈溢出。
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-18
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多