问题描述
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。)
解决方法
tl; dr:每个类字段(无论是否静态)都在内部包装在一个方法中,该方法在某个时刻被相应的接收方(类或实例)调用。
因此,我不确定其中一些细节*,但基本上会发生这种情况:
对于每个带有初始化程序的字段(静态或非静态),都会创建一个函数/方法,并将初始化程序作为其主体。所以这个
static foo = () => this.v;
内部成为某物
function () { () => this.v }
那是在步骤28的the proposal中,最终导致了ClassFieldDefinitionEvaluation
in this spec。该方法在步骤3.e中创建。
然后获取静态字段(现在是方法),并以类对象本身作为 receiver 进行调用(即,将中间方法内的this
值设置为类对象) )。这发生在步骤34.a中,导致到DefineField
in this spec。最后,将返回值(在您的情况下为箭头函数)用作实际属性的值。
用代码表示,大致是这样:
class Foo {}
Foo.v = function() { return 123; }.call(Foo);
Foo.bar = function() { return () => this.v; }.call(Foo);
*:我还不清楚中间方法如何返回值,但是可能有些东西说返回了函数体的最后一个表达式。