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/