为什么箭头函数作为静态成员值没有词法作用域?

Why are arrow functions as static members values not lexically scoped?

class Foo {
  static v = 123;

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

console.log(Foo.bar());

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

然而,它 returns 123

为什么会发生这种情况?

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

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


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

对于每个带有初始值设定项(静态或非静态)的字段,都会创建一个 function/method,并以初始值设定项作为其主体。所以这个

static foo = () => this.v;

内部变成了这样的东西

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

the proposal in step 28, which eventually leads to ClassFieldDefinitionEvaluation in this spec 中。该方法是在步骤 3.e.

中创建的

然后使用 class 对象本身作为 receiver 获取并调用静态字段(现在是方法)(即内部的 this 值该中间方法设置为 class 对象)。这发生在步骤 34.a 中,导致 DefineField in this spec。最后 return 值(在您的例子中是箭头函数)用作实际 属性.

的值

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

class Foo {}

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

*:我不是很清楚中间方法returns的值是怎么来的,不过大概有说是函数的最后一个表达式body 是 returned 之类的。