最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Typescript: calling super method from extended class gives type error - (intermediate value) is not a function - St

programmeradmin0浏览0评论

I am implementing event handling in a component named StructureWindowComponent and also have an override for it in LeggerStructureWindowComponent..

In the base class (StructureWindowComponent) the event handling for blur event is as follows:

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

I am implementing event handling in a component named StructureWindowComponent and also have an override for it in LeggerStructureWindowComponent..

In the base class (StructureWindowComponent) the event handling for blur event is as follows:

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

In the derived class LeggerStructureWindowComponent, I am calling this method using super like this...

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

I get the error in the console: ERROR TypeError: (intermediate value).symbolCellLostFocus is not a function

Not sure what is wrong here.. can someone please advice?

Share Improve this question edited Oct 23, 2020 at 10:57 R. Richards 25.2k10 gold badges66 silver badges65 bronze badges asked Oct 23, 2020 at 10:46 Teja ReddyTeja Reddy 1011 silver badge4 bronze badges 2
  • I think you might need to add a semicolon behind the closing curly braces. Btw., is there a reason why you don't make these named functions? – Gunnar B. Commented Oct 23, 2020 at 11:26
  • Gunnar, I have just shown small part of the code. There is more logic after that. Thanks for the suggestion though – Teja Reddy Commented Oct 23, 2020 at 14:00
Add a comment  | 

1 Answer 1

Reset to default 20

This is a tricky one, but it has to do with the use of arrow functions syntax in classes, and the prototype chain. It is not related to Angular specifically.

Basically if you want to fix your issue, you need to replace a = () => { ... } with a() { ... }:

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

Now for the explanation, if you write the following snippet:

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

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

It is transformed into this JavaScript snippet:

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();
        };
    }
}

As you can see, the methods are defined in the constructor, for each instance created by the constructors. This means that the method sayHello from A is not available for B, because sayHello is not available in the prototype of B (which is A), it is only available for each instance of A. This can be confusing, I highly recommend learning about prototype inheritance in JavaScript!

Classes, introduced in ES2015, are just syntactic sugar for prototype inheritance in JavaScript. The class, constructor, super, etc. keywords only abstract the syntax needed to write prototype chains. Essentially, it's the way to achieve composition and inheritance in JavaScript, a very powerful concept.

Anyway, when you write super.X() here, the JavaScript engine is trying to access the X method on the prototype, which doesn't exist. You end up with Object.getPrototypeOf(this).undefined(), and undefined is indeed not a function, so you get a TypeError: (intermediate value).sayHello is not a function runtime error.

Here's an example to illustrate what I said: TS playground.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论