繁体   English   中英

JavaScript:超类中的“this”指的是子类

[英]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 这意味着BA A有一个特定的合同,例如它从它的createObject方法返回一个 object。 通过更改B中的返回类型,您将违反该合同。 B不再是A ,它是类似于A的东西,除了createObject

所以我建议不要这样做,因为它违反了子类化规则之一。

可以A中的代码调用AcreateObject版本,如下所示:

object = A.prototype.createObject.call(this, this.objecttypes[i].template);

但我强烈建议您不要这样做。 :-) 相反,不要让B违反A的合同。 对您在B中所做的事情使用不同的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM