如何在 js ES6 的多态中使用 this 和 super

How to use this and super in polymorphism in js ES6

我想要 3 个 class 是相关的。一个 Node class 一个 DoorNode class 和一个 SisterDoorNode class.

有不同类型的节点,它们都有一个 ID、一个位置、连接和一些功能。

其中一种类型是门节点,它与姊妹门节点一样,具有节点类型 "door"、相应的元素和一些功能。他们的id和position是用一种方式计算的。

然后还有姐妹门节点。他们有不同的方法来计算 id 和位置,还有一个布尔值表明他们是姊妹门节点。

这就是我想要的样子:

class Node {
    constructor(id, pos) {
        this.id = id;
        this.pos = pos;
        this.connections = [];
    }

    addConnection(c) {
        //A few functions all nodes need
    }
}

class DoorNode extends Node {
    constructor(door) {
        //Both of these are needed for all Nodes but are calculated in a different way for DoorNode and SisterDoorNode
        let id = this.getId(door);
        let pos = this.getPos(door);
        super(id, pos);

        //Both of these are needed in SisterDoorNode and DoorNode
        this.nodeType = "door";
        this.correspondingElement = door;
    }

    getId(door) {
        return door.id;
    }

    getPos(door) {
        return door.pos;
    }

    getDoorSize() {
        //Some calculations I need for both DoorNode + SisterDoorNode
    }
}

class SisterDoorNode extends DoorNode {
    constructor(door) {
        super(door);
        this.isSisterNode = true;
    }

    getId(door) {
        return door.id + ".2";
    }

    getPos(door) {
        return new Point(door.pos.x + 10, door.pos.y + 10);
    }
}

但是因为我不能在 super() 之前使用 this 这不起作用。解决这个问题的最佳方法是什么?

因此,您对无法在 'super' 之前使用 'this' 深信不疑,因为在基础 class 之前没有 'this' 可引用'构造函数已完成 运行.

对此有一些解决方案,但它们涉及重构您的代码。

1) 传入 idpos 作为参数,就像基础 class 所做的那样。

2) 制作 getIdgetPos 静态方法。 (这将引入使用静态变量的新复杂性)

3) 使 posid 可选,并在 super 调用后的某个时间设置它们。

4) 直接引用道具即可; super( door.id, door.pos ),但这在 idpos

上执行逻辑的扩展 class 中不起作用

更新以包含通过超级调用使用静态函数的示例。

class Foo {
    constructor(door) {
        super( Foo.GetNodeFromDoor( door ) );
        // can now use `this`
    }
    
    
    static GetNodeFromDoor( door ) {
      // `this` refers to the static namespace, and not to the instance of the class. 
      return {
        id: door.id + ".2",
        pos: new Point(
          door.pos.x + 10,
          door.pos.y + 10
        )
      }
    }
}