Typescript:从扩展类调用超级方法会出现类型错误 - (中间值)不是函数

Tej*_*ddy 10 javascript event-handling super typescript angular

我正在名为 StructureWindowComponent 的组件中实现事件处理,并且还在 LeggerStructureWindowComponent 中对其进行了覆盖。

在基类(StructureWindowComponent)中,模糊事件的事件处理如下:

symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
    console.log("base class symbol cell lost focus");
    //implementation...
  }
Run Code Online (Sandbox Code Playgroud)

在派生类 LeggerStructureWindowComponent 中,我使用 super 调用此方法,如下所示...

symbolCellLostFocus = (symbolField : MatInput, $index: number) =>{
    console.log("derived class symbol lost focus");
    super.symbolCellLostFocus(symbolField, $index);
  }
Run Code Online (Sandbox Code Playgroud)

我在控制台中收到错误: ERROR TypeError: (intermediate value).symbolCellLostFocus is not a function

不知道这里出了什么问题..有人可以请建议吗?

Ben*_*oit 20

这是一个棘手的问题,但它与类中箭头函数语法的使用以及原型链有关。它与 Angular 没有具体关系。

基本上,如果您想解决问题,您需要替换a = () => { ... }a() { ... }

symbolCellLostFocus(symbolField : MatInput, $index: number) {
  console.log("base class symbol cell lost focus");
  //implementation...
}
Run Code Online (Sandbox Code Playgroud)
symbolCellLostFocus(symbolField : MatInput, $index: number) {
  console.log("derived class symbol lost focus");
  super.symbolCellLostFocus(symbolField, $index);
}
Run Code Online (Sandbox Code Playgroud)

现在为了解释,如果您编写以下代码片段:

class A {
    name = 'A'
    sayHello = () => {
        console.log('Hello from A')
    }
}

class B extends A {
    name = 'B'
    sayHello = () => {
        console.log('Hello from B')
        super.sayHello()
    }
}
Run Code Online (Sandbox Code Playgroud)

它被转换成这个 JavaScript 片段:

class A {
    constructor() {
        this.name = 'A';
        this.sayHello = () => {
            console.log('Hello from A');
        };
    }
}
class B extends A {
    constructor() {
        super(...arguments);
        this.name = 'B';
        this.sayHello = () => {
            console.log('Hello from B');
            super.sayHello();
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,对于构造函数创建的每个实例,方法都是在构造函数中定义的。这意味着sayHellofrom 的方法A不适用于B,因为sayHello在 的原型B(即A)中不可用,它仅适用于 的每个实例A。这可能会令人困惑,我强烈建议学习 JavaScript 中的原型继承!

ES2015 中引入的类只是 JavaScript 中原型继承的语法糖。class constructor 、等关键字super仅抽象编写原型链所需的语法。本质上,它是在 JavaScript 中实现组合和继承的方式,这是一个非常强大的概念。

不管怎样,当你super.X()在这里写的时候,JavaScript 引擎正在尝试访问X原型上的方法,而该方法并不存在。你最终得到Object.getPrototypeOf(this).undefined(), 并且undefined确实不是一个函数,所以你会得到一个TypeError: (intermediate value).sayHello is not a function运行时错误。

这里有一个例子来说明我所说的:TS游乐场