javascript - 为什么箭头函数作为静态成员值没有词法范围?

标签 javascript static es6-class ecmascript-next class-fields

class Foo {
  static v = 123;

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

console.log(Foo.bar());

我希望此代码返回 undefined ,因为箭头函数是词法范围的,因此 this必须急切地绑定(bind)到外部范围。
然而,它返回 123 .
为什么会发生这种情况?
是的,我知道它仍然是第 3 阶段,但仍然 - 为什么提议的标准会这样? (另一个例子见 https://babeljs.io/docs/en/babel-plugin-transform-class-properties。)

最佳答案

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

所以,我不确定其中一些细节*,但基本上会发生这种情况:
对于每个带有初始化器(静态或非静态)的字段,都会创建一个函数/方法,初始化器作为它的主体。所以这

static foo = () => this.v;
在内部变成这样
function () { () => this.v }
那是在the proposal在步骤 28 中,最终导致 ClassFieldDefinitionEvaluation in this spec .该方法在步骤 3.e 中创建。
然后获取静态字段(现在是方法)并使用类对象本身作为接收者调用(即,该中间方法内的 this 值设置为类对象)。这发生在步骤 34.a 中,导致 DefineField in this spec .最后,返回值(在您的情况下为箭头函数)用作实际属性的值。
用代码表示,大致是这样的:
class Foo {}

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

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

关于javascript - 为什么箭头函数作为静态成员值没有词法范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63937663/

相关文章:

javascript - 将特定实例的特定方法作为参数传递

javascript - NestJS 在服务类中丢失此内部函数方法的上下文

javascript - 永久更改滚动代码

asp.net - Javascript 弹出窗口打开函数

javascript - JavaScript 和 Moment.js 无法正确评估日期范围内的日期

c++ - 如何在第一次使用之前将静态数组保留在内存之外

javascript - ES6 类是如何编译的?

javascript - 切换(plotly.js - 分散)y 轴和迹线的可见性

ruby - 变量声明: difference between "@@" and "class << self"

Java 8,静态方法与函数