代码之家  ›  专栏  ›  技术社区  ›  Ar3s

在调用“super(…)”之前将“this”向前关闭(或:“wtf令人费解的故事,非常严肃”)

  •  0
  • Ar3s  · 技术社区  · 7 年前

    经过一番摆弄,我最终用打字机写了这篇文章:

     class B extends A{
         constructor() {
             const c = new C(() => this.method());
             super(c);
             c.someMethod(this);
         }
     }
    

    而且有效…

    让我们暂且不谈我为什么这么做(与我的问题无关)

    我的问题是:

    • 当我在调用 super 是吗?啊!
    • 这条线怎么能 const c = new C(() => this.method()); 关闭 this 什么时候还没有定义?
      • 至少 不应该有,否则我宁愿 const c = new C(this.method); 但它没有编译,抱怨 this is not, yet, available 是的。

    我错过了一些东西:/

    1 回复  |  直到 7 年前
        1
  •  2
  •   jcalz    7 年前

    是的,我想我明白为什么这会困扰你了。github中的相关问题是 Microsoft/TypeScript#3311 是的。看看我能否回答这些问题:


    • 当我在调用 super 是吗?啊!

    显然是因为 you don't have member initializers 是的。从相关问题:

    你可以打电话 超级的 如果你没有成员初始值设定项…

    如果您看看类成员初始化器是如何发出的,那么这方面的原因就相当清楚了。成员初始值设定项在超级调用之后发出(否则派生类初始值设定项无法正确覆盖基类初始值设定);通过将超级调用强制为编译器首先可以保证只有一个(正确的)位置发出这些初始值设定项。

    通过移除成员初始值设定项,您可以将超级调用移动到任何位置——这将明确显示每个类成员的初始化顺序。

    我认为语言设计师认为在 超级的 调用(例如,进行一些计算以确定传入调用的对象 超级的 ,但有几个问题是有问题的:成员初始值设定项(作为对 this )和显式引用 是的。


    • 至少这个不应该有,否则我宁愿做 c = new C(this.method); 但它没有编译,抱怨 this is not, yet, available

    对,你不能指裸体 this.method 在呼叫之前 超级的 因为 不保证当时存在。


    • 这条线怎么能 const c = new C(() => this.method()); 关闭 什么时候还没有定义?

    我对被接受的闭包的猜测是 不能认为是来了 lexically before 这个 超级的 打电话来。这可能是也可能不是编译器中的错误或设计限制。在你的例子中,如果 C 实际上没有调用函数,那么可能没有问题…闭包可能会延迟对 本方法 直到子类构造函数完成。但是由于 C类 可以 调用函数,代码可能不安全。

    如果您强烈认为这会给编译器一个警告,那么您可能希望在github和reference中引发一个问题 微软/typescript 3311 (你不能评论这个问题,因为它已经被锁定了)。

    希望能有所帮助。祝你好运!