如何在js ES6中使用this和super in polymorphism

时间:2019-04-18 23:18:06

标签: javascript polymorphism this super es6-class

我想拥有3个相关的类。 Node 类, DoorNode 类和 SisterDoorNode 类。

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

这些类型之一是门节点,就像姊妹门节点一样,其节点类型为“门”,相应的元素和一些功能。它们的ID和位置是用一种方法计算的。

然后,还有姐妹门节点。它们具有不同的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 ,因此无法正常工作。解决此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

因此,您对不能在“超级”之前使用“ this”感到沮丧,因为在基类的构造函数运行完成之前没有“ this”可以引用。

有一些解决方案,但是涉及重组代码。

1)就像基本类一样,将idpos作为参数传递。

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

3)将posid设为可选,并在超级调用之后的某个时间进行设置。

4)您可以直接引用道具; super( door.id, door.pos ),但不适用于在idpos

上进行逻辑处理的扩展类

更新为包括将静态函数与超级调用配合使用的示例。

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
        )
      }
    }
}