在子 class 的静态方法中调用父 class 的构造函数

Calling constructor of parent class in static method of child class

我在子静态方法中调用 super 时遇到问题。

const _todos = [];

class Todo {
  constructor(title) {
    this.title = title;
    this.id = Math.round(Math.random() * 100);
    _todos.push({title, id: this.id});

    console.log(`Todo ID: ${this.id}. DONT FORGET IT!`);
  }

  static TodoerVersion = '1.8';

  static removeTodo(id) {
    const todoIndex = _todos.findIndex(t => t.id == id);
    _todos.splice(todoIndex, 1);
  }
}

class TodoV2 extends Todo {
  static addTodo(title) {
    super(title);
  }

  static addDescription(todo, description) {
    todo.description = description;
  }

  static TodoerVersion = '2.0';
};

new TodoV2("play guitar");

为什么不起作用? 但是如果我用普通方法调用 super,它会工作得很好。

super 只能在 class.

的构造函数中调用

给你两个答案:

  1. 您实际提出的问题。

  2. 我认为你应该做的。 :-)

正在回答您提出的问题:

JavaScript在这方面非常特殊:thisstatic方法中有意义(只要你正确调用它们,例如 TodoV2.addTodo("title")): 这是你调用静态方法的构造函数。一个 subclass 构造函数继承自它的 superclass 构造函数(是的,真的)。因此,您可以在 static 方法中使用 Object.getPrototypeOf(this) 访问父 class 的构造函数:

// This is something unusual that JavaScript actually does support
static addTodo(title) {
    const ctor = Object.getPrototypeOf(this);
    return new ctor(title);
}

要处理用户可能以未设置 this 的方式调用 addTodo 的情况,您可以执行类似这样的操作以默认为 TodoV2 如果 thisundefined:

static addTodo(title) {
    const ctor = Object.getPrototypeOf(this ?? TodoV2);
    return new ctor(title);
}

我认为你应该怎么做

您不应该为此使用静态方法。相反,为 TodoV2:

定义构造函数
class TodoV2 extends Todo {
    constructor(title, description) {
        super(title);
        this.description = description ?? "";
    }

    static addTodo(title) { // Why no `description`?
        return new this(title); // Or `new TodoV2(title)`
    }
}

如果您希望子classes创建超classes的实例,您也可以查看Symbol.species模式。