8

class Foo {
  static v = 123;

  static bar = () => this.v;
}

console.log(Foo.bar());

我希望这段代码返回undefined,因为箭头函数是词法范围的,因此this必须急切地绑定到外部范围。

然而,它回来了123

为什么会发生这种情况?

是的,我知道它仍然是第 3 阶段,但仍然 - 为什么提议的标准会这样?(有关另一个示例,请参见https://babeljs.io/docs/en/babel-plugin-transform-class-properties。)

4

1 回答 1

7

tl;dr:每个类字段(静态或非静态)都在内部包装在一个方法中,该方法在某个时候被相应的接收器(类或实例)调用。


所以,我不确定其中一些细节*,但基本上会发生这种情况:

对于每个带有初始化器(静态或非静态)的字段,都会创建一个函数/方法,初始化器作为它的主体。所以这

static foo = () => this.v;

在内部变成这样

function () { () => this.v }

这在第 28 步的提案中,最终导致ClassFieldDefinitionEvaluation在这个规范中。该方法在步骤 3.e 中创建。

然后获取静态字段(现在是方法)并使用类对象本身作为接收者调用(即,this将中间方法内的值设置为类对象)。这发生在步骤 34.a 中,这导致DefineField了本规范。最后,返回值(在您的情况下为箭头函数)用作实际属性的值。

用代码表示,大致是这样的:

class Foo {}

Foo.v = function() { return 123; }.call(Foo);
Foo.bar = function() { return () => this.v; }.call(Foo);

*:我不太清楚中间方法是如何返回值的,但是可能有说返回函数体的最后一个表达式什么的。

于 2020-09-17T13:01:17.343 回答