[英]JavaScript: 'this' in superclass refers to subclass
我正在從子類調用超類方法。 當從子類調用時,超類方法中的“this”不再指代超類,而是指調用它的子類。 這會導致 inheritance 出現問題。
詳情如下:
在我的項目中,我使用 class 從注冊類型構造對象。 這些類型是從屬性中注冊的,或者是從基於已定義類型的模板中注冊的:
class A{
createObject(type) {
let object = null;
for (let i in this.objecttypes) {
if (this.objecttypes[i].type == type) {
if (this.objecttypes[i].template) {
object = this.createObject(this.objecttypes[i].template);
object.type = type;
}
else
object = new TestObject(type);
for (const aname in this.objecttypes[i].attributes)
object.set(aname, this.objecttypes[i].attributes[aname]);
//console.log("Object: "+JSON.stringify(object));
}
}
return object;
}
}
這在超類中運行良好。 但是,我還構建了一個具有更用戶友好方法的子類。 在子類中,名為“createObject”的方法不返回創建的 object。 它存儲它並返回 object id:
class B extends A{
createObject(type,otherargs){
let object=super.createObject(type);
this.objects.set(object.id,object);
/* do things with otherargs */
return object.id;
}
}
/* Method to test function. In test class */
templateObjects(){
let container=this.getContainer();
console.log("proto: "+JSON.stringify(Object.getPrototypeOf(container)));
let tt=App.createObjectType("template1","",[{name:"attr0",value:1},{name:"attr1",value:2},{name:"attr2",value:3}]);
let ut=App.createObjectType("test","template1",[{name:"attr3",value:66}]);
container.addObjectType(tt);
container.addObjectType(ut);
let o0=container.createObject("template1");
console.log("Object: "+JSON.stringify(o0));
let o1=container.createObject("test");
console.log("Object: "+JSON.stringify(o1));
}
當我現在嘗試從子類創建基於模板的對象時,超類代碼就到了這一點:
if (this.objecttypes[i].template) {
object = this.createObject(this.objecttypes[i].template);
object.type = type;
}
'this.createObject(...)' 調用導致調用子類的 createObject 方法,從而返回一個數字鍵,並且嘗試為其分配類型失敗。
我知道我可以例如重命名子類中的方法以避免問題,我可以發送 class object(“this”)作為參數或其他棘手的東西。
但是有沒有更直接、更慣用的方法來解決這個問題?
this
是指 object,而不是 class。 在這種情況下,它是正常使用的B
實例(即使在A
中的代碼中——只有一個對象)。 由於 object 的createObject
屬性來自B
,這就是您從this.createObject
獲得的(無論該代碼出現在何處)。
但是還有一個更根本的問題:
當您子類化某些東西時,您是在說它是您子類化的東西的更專業的版本。 也就是說, B
是專門A
。 這意味着B
是A
。 A
有一個特定的合同,例如它從它的createObject
方法返回一個 object。 通過更改B
中的返回類型,您將違反該合同。 B
不再是A
,它是類似於A
的東西,除了createObject
。
所以我建議不要這樣做,因為它違反了子類化規則之一。
您可以從A
中的代碼調用A
的createObject
版本,如下所示:
object = A.prototype.createObject.call(this, this.objecttypes[i].template);
但我強烈建議您不要這樣做。 :-) 相反,不要讓B
違反A
的合同。 對您在B
中所做的事情使用不同的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.