在调用 `super(...)` 之前前向关闭 `this`(或者:"the mind-bending story of WTF seriously")
Forward-closure of `this` before calling `super(...)` (or: "the mind-bending story of WTF seriously")
经过一些摆弄,我最终用 TypeScript 写了这个:
class B extends A{
constructor() {
const c = new C(() => this.method());
super(c);
c.someMethod(this);
}
}
而且有效...
暂时搁置为什么我这样做(与我的问题无关)
我的问题是:
- 当我在调用
super
之前做一些事情时,它到底是如何编译的?!
- 行
const c = new C(() => this.method());
如何在尚未定义时关闭this
?
- 至少
this
不应该可用或者我宁愿完成 const c = new C(this.method);
但它没有编译,抱怨 this is not, yet, available
.
我遗漏了一些东西 :/
是的,我想我明白为什么这会困扰你。 GitHub 中的相关问题是 Microsoft/TypeScript#3311。让我们看看我能否回答这些问题:
- How in the world does it compile when I do things before the call to
super
?!
显然是因为 you don't have member initializers。来自链接问题:
You can call super
whenever you want if you don't have member initializers...
If you look at how class member initializers are emitted, the reasoning for this becomes fairly clear. Member initializers are emitted after the super call (otherwise your derived-class initializers wouldn't properly overwrite base class initializations); by enforcing the super call to be the first thing the compiler can guarantee that there's exactly one (correct) place to emit those initializers.
You move the super call to any position by removing member initializers -- this makes explicit what you expect the initialization order of each class member to be.
我认为语言设计者认为在 super
调用之前可以做一些合法的事情(例如,进行一些计算以确定要传递给 super
的调用的内容),但是有几件事是有问题的:成员初始值设定项(它作为对 this
的引用发送给 JS),以及对 this
的显式引用。
- at least this should not be available or I'd rather have done const
c = new C(this.method);
but it did not compile, complaining that this is not, yet, available
是的,你不能在调用super
之前引用裸this.method
,因为那时this
不一定存在。
- How can the line
const c = new C(() => this.method());
closure this
when it is not yet defined ?
我对闭包被接受的猜测是,对 this
的引用不能被视为来自 lexically before super
调用。这可能是也可能不是编译器中的错误或设计限制。在你的情况下,如果 C
的构造函数实际上没有调用函数,那么可能没有问题......闭包可能会推迟 this.method
的取消引用,直到子类构造函数完成之后.但是由于 C
的构造函数可能 调用函数,代码可能不安全。
如果您强烈认为这应该给出编译器警告,您可能想在 GitHub 中提出问题并参考 Microsoft/TypeScript#3311(您无法评论该问题,因为它已被锁定).
希望对您有所帮助。祝你好运!
经过一些摆弄,我最终用 TypeScript 写了这个:
class B extends A{
constructor() {
const c = new C(() => this.method());
super(c);
c.someMethod(this);
}
}
而且有效...
暂时搁置为什么我这样做(与我的问题无关)
我的问题是:
- 当我在调用
super
之前做一些事情时,它到底是如何编译的?! - 行
const c = new C(() => this.method());
如何在尚未定义时关闭this
?- 至少
this
不应该可用或者我宁愿完成const c = new C(this.method);
但它没有编译,抱怨this is not, yet, available
.
- 至少
我遗漏了一些东西 :/
是的,我想我明白为什么这会困扰你。 GitHub 中的相关问题是 Microsoft/TypeScript#3311。让我们看看我能否回答这些问题:
- How in the world does it compile when I do things before the call to
super
?!
显然是因为 you don't have member initializers。来自链接问题:
You can call
super
whenever you want if you don't have member initializers...If you look at how class member initializers are emitted, the reasoning for this becomes fairly clear. Member initializers are emitted after the super call (otherwise your derived-class initializers wouldn't properly overwrite base class initializations); by enforcing the super call to be the first thing the compiler can guarantee that there's exactly one (correct) place to emit those initializers.
You move the super call to any position by removing member initializers -- this makes explicit what you expect the initialization order of each class member to be.
我认为语言设计者认为在 super
调用之前可以做一些合法的事情(例如,进行一些计算以确定要传递给 super
的调用的内容),但是有几件事是有问题的:成员初始值设定项(它作为对 this
的引用发送给 JS),以及对 this
的显式引用。
- at least this should not be available or I'd rather have done const
c = new C(this.method);
but it did not compile, complaining thatthis is not, yet, available
是的,你不能在调用super
之前引用裸this.method
,因为那时this
不一定存在。
- How can the line
const c = new C(() => this.method());
closurethis
when it is not yet defined ?
我对闭包被接受的猜测是,对 this
的引用不能被视为来自 lexically before super
调用。这可能是也可能不是编译器中的错误或设计限制。在你的情况下,如果 C
的构造函数实际上没有调用函数,那么可能没有问题......闭包可能会推迟 this.method
的取消引用,直到子类构造函数完成之后.但是由于 C
的构造函数可能 调用函数,代码可能不安全。
如果您强烈认为这应该给出编译器警告,您可能想在 GitHub 中提出问题并参考 Microsoft/TypeScript#3311(您无法评论该问题,因为它已被锁定).
希望对您有所帮助。祝你好运!