[英]Typescript: calling super method from extended class gives type error - (intermediate value) is not a function
I am implementing event handling in a component named StructureWindowComponent and also have an override for it in LeggerStructureWindowComponent..我正在一个名为 StructureWindowComponent 的组件中实现事件处理,并且在 LeggerStructureWindowComponent 中也有一个覆盖它。
In the base class (StructureWindowComponent) the event handling for blur event is as follows:在基类(StructureWindowComponent)中,模糊事件的处理如下:
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...在派生类 LeggerStructureWindowComponent 中,我像这样使用 super 调用此方法...
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我在控制台中收到错误消息:ERROR TypeError: (intermediate value).symbolCellLostFocus is not a function
Not sure what is wrong here.. can someone please advice?不知道这里出了什么问题..有人可以请教吗?
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.
它与 Angular 没有特别的关系。
Basically if you want to fix your issue, you need to replace a = () => { ... }
with a() { ... }
:基本上,如果你想解决你的问题,你需要用
a() { ... }
替换a = () => { ... }
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:它被转换成这个 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();
};
}
}
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
.这意味着来自
A
的方法sayHello
不可用于B
,因为sayHello
在B
的原型(即A
)中不可用,它仅可用于A
每个实例。 This can be confusing, I highly recommend learning about prototype inheritance in JavaScript!这可能会令人困惑,我强烈建议您学习 JavaScript 中的原型继承!
Classes, introduced in ES2015, are just syntactic sugar for prototype inheritance in JavaScript. ES2015 中引入的类只是 JavaScript 中原型继承的语法糖。 The
class
, constructor
, super
, etc. keywords only abstract the syntax needed to write prototype chains. class
、 constructor
、 super
等关键字仅抽象了编写原型链所需的语法。 Essentially, it's the way to achieve composition and inheritance in JavaScript, a very powerful concept.本质上,它是在 JavaScript 中实现组合和继承的方式,这是一个非常强大的概念。
Anyway, when you write super.X()
here, the JavaScript engine is trying to access the X
method on the prototype, which doesn't exist.无论如何,当您在这里编写
super.X()
,JavaScript 引擎正在尝试访问原型上不存在的X
方法。 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.你最终得到
Object.getPrototypeOf(this).undefined()
,而undefined
确实不是一个函数,所以你得到一个TypeError: (intermediate value).sayHello is not a function
运行时错误。
Here's an example to illustrate what I said: TS playground .这里有一个例子来说明我所说的: TS playground 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.