如何在 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) 传入 id
和 pos
作为参数,就像基础 class 所做的那样。
2) 制作 getId
和 getPos
静态方法。 (这将引入使用静态变量的新复杂性)
3) 使 pos
和 id
可选,并在 super 调用后的某个时间设置它们。
4) 直接引用道具即可; super( door.id, door.pos )
,但这在 id
和 pos
上执行逻辑的扩展 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
)
}
}
}
我想要 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) 传入 id
和 pos
作为参数,就像基础 class 所做的那样。
2) 制作 getId
和 getPos
静态方法。 (这将引入使用静态变量的新复杂性)
3) 使 pos
和 id
可选,并在 super 调用后的某个时间设置它们。
4) 直接引用道具即可; super( door.id, door.pos )
,但这在 id
和 pos
更新以包含通过超级调用使用静态函数的示例。
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
)
}
}
}