[英]Is there a wasy to emulate super with mixins in typescript?
我通過 Mixins 使用多重繼承(使用替代模式)。 有沒有辦法用這種模式獲得類似於“超級”的東西? 考慮這里的例子
abstract class Activatable{
private activated: boolean = false;
constructor(){}
public activate(): void {
this.activated = true;
console.log('Activatable activated')
}
}
class SomethingElse{};
interface ThingParent extends Activatable{}
class ThingParent extends SomethingElse{
public activate(): void {
(this as Activatable).activate();
let addSomeValueHere = true;
console.log('Thing parent activated')
}
}
applyMixins(ThingParent, [Activatable]);
class Thing extends ThingParent {
constructor(){
super()
}
public activate(): void {
super.activate();
console.log('Thing activated');
}
}
let thing = new Thing();
thing.activate();
function applyMixins(derivedCtor: any, constructors: any[]) {
constructors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
Object.create(null)
);
});
});
}
Thing 擴展了 ThingParent,它通過 mixins 擴展了一個名為 Activatable 的類。 當我在 Thing 上調用 activate 時,我也想在 ThingParent 和 Activatable 上調用 activate,但它只在 Activatable 上調用。
如果我更改 ThingParent 上的函數名稱,我可以直接調用該函數,但 ThingParent 無法通過 super 訪問 Activatable(因為它擴展了 SomethingElse)。 然后我必須從 thing.activate() 調用 super.activate() 和 this.thingParentActivate() 所以這是我想盡可能避免的模式。
有替代方案嗎?
如您所知,JavaScript 類不支持多重繼承,因此如果您想獲得這種效果,您需要做一些事情來模擬它。 Mixin是實現此目的的一種方法,但它們並不真正支持沖突的方法名稱。 如果您有沖突的方法名稱,那么 mixins 最終會破壞除其中一個之外的所有方法,這不是您想要的。
如果您想在“子類”的實例上調用特定的“超類”方法,您可以直接使用Function.prototype.call()
來執行this
操作,並將實例作為 this arg。 而不是Activatable::activate()
,您調用Activatable.prototype.activate.call(this);
.
讓我們試一試:
interface ThingParent extends Activatable { }
class ThingParent extends SomethingElse {
public activate(): void {
Activatable.prototype.activate.call(this);
let addSomeValueHere = true;
console.log('Thing parent activated')
}
}
class Thing extends ThingParent {
constructor() {
super()
}
public activate(): void {
ThingParent.prototype.activate.call(this);
console.log('Thing activated');
}
}
let thing = new Thing();
thing.activate();
// [LOG]: "Activatable activated"
// [LOG]: "Thing parent activated"
// [LOG]: "Thing activated"
這可以編譯並產生您期望的輸出。
在更復雜的場景中,您可能會決定需要組合使用 mixins 和直接方法call
。 或者其他一些方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.