当每个类包含一个具有相同名称的方法时,我在访问层次结构中的方法时遇到了问题。
class A {
constructor(private name: string) { }
notify() { alert(this.name) }
}
class B extends A {
constructor() {
super("AAA")
}
notify() {alert("B") }
}
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
super.notify(); // this alerts "B"
// How to call notify() of the class A so it alerts "AAA"?
}
}
new C().callA();
答案 0 :(得分:3)
虽然我质疑要求您执行此操作的设计,但您可以通过获取A.prototype
的原始方法并使用call
轻松解决此问题:
class C extends B {
notify() { alert("C") }
callA() {
A.prototype.notify.call(this);
}
}
答案 1 :(得分:1)
通过爬上原型链可以达到祖父母方法:
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
const grandparentNotify = super.__proto__.notify;
grandparentNotify.call(this); // this alerts "AAA"
}
}
__proto__
用于说明目的,因为获取对象原型的正确方法是Object.getPrototypeOf
。请注意,grantparent原型的super.__proto__
链在实现之间可能不同(例如TypeScript和native)。
不应该达到祖父母方法,因为这表明设计问题;孙子不应该知道祖父母的方法。在方法中使用call
是类设计出错的另一个迹象。
如果需要在扩展类中使用来自另一个类的方法(它是否真的无关紧要),这应该通过mixin明确地完成。由于C
并不需要所有祖父方法,并且需要避免命名冲突,因此应直接指定方法:
interface C {
grandparentNotify(): void;
}
class C extends B {
notify() { alert("C") }
callA() {
this.notify(); // this alerts "C"
this.grandparentNotify(); // this alerts "AAA"
}
}
C.prototype.grandparentNotify = A.prototype.notify;
接口已合并,键入系统将grandparentNotify
接受为C
方法。这种方式看起来很原始,但这是分配方法的惯用方法。
提供一些开销但不需要接口合并的更平滑的方法是getter:
class C extends B {
notify() { alert("C") }
get grandparentNotify() {
return A.prototype.notify;
}
callA() {
this.notify(); // this alerts "C"
this.grandparentNotify(); // this alerts "AAA"
}
}