如何创建一个从 class 创建新实例的方法?

how to create a method which creates new instance from class?

我有 Bmw class 从我之前创建的 Car class 扩展而来,现在我需要在 Bmw 中创建一个 createNewBmwCar 方法] class 将从 Bmw class...

创建新实例

class Bmw extends Car {
  constructor(options) {
    this._model = options.model;
    this._year = options.year;
    this._price = options.price;
  }
  static createNewBmwCar() {
    // return FIXME: let newCar = new Bmw();
  }
}

您需要在此 static 方法中实例化 Bmw

class Car {};

class Bmw extends Car {
  constructor(options) {
    super(options);
    this._model = options.model;
    this._year = options.year;
    this._price = options.price;
  }
  static createNewBmwCar(options) {
    return new Bmw({
        model: "BMW",
        year: options.year,
        price: options.price
    });
  }
}

let myBMW = Bmw.createNewBmwCar({
    year: 2020,
    price: "1$"
});

console.log(myBMW);

问题不在于 static 方法,而是构造函数。派生构造函数 必须 调用 super(),并且必须这样做才能使用 this.

如果您修复该问题,并将必要的参数添加到 createNewBmwCar,它会起作用(但请继续阅读):

class Car { }
class Bmw extends Car {
    constructor(options) {
        super(); // <=========
        this._model = options.model;
        this._year = options.year;
        this._price = options.price;
    }
    static createNewBmwCar(options) {
        let newCar = new Bmw(options);
        return newCar;
    }
}

const beemer = Bmw.createNewBmwCar({
    model: "fancy",
    year: "recent",
    price: "lots",
});
console.log(beemer._model); // "fancy"

您还有第二个可能更灵活的选项:您可以在 static 方法中使用 this 而不是 Bmw,因为它将引用您调用的构造函数静态方法:

static createNewBmwCar(options) {
    let newCar = new this(options);
    //               ^^^^
    return newCar;
}

class Car { }
class Bmw extends Car {
    constructor(options) {
        super(); // <=========
        this._model = options.model;
        this._year = options.year;
        this._price = options.price;
    }
    static createNewBmwCar(options) {
        let newCar = new Bmw(options);
        return newCar;
    }
}

const beemer = Bmw.createNewBmwCar({
    model: "fancy",
    year: "recent",
    price: "lots",
});
console.log(beemer._model); // "fancy"

这样做的好处是,如果您创建 Bmw 的子类,然后在子类上调用 static 方法,您将获得子类的实例,而不是 Bmw:

class Car { }
class Bmw extends Car {
    constructor(options) {
        super(); // <=========
        this._model = options.model;
        this._year = options.year;
        this._price = options.price;
    }
    static createNewBmwCar(options) {
        let newCar = new this(options);
        return newCar;
    }
}
class BmwSpecial extends Bmw { }

const beemer = BmwSpecial.createNewBmwCar({
    model: "fancy",
    year: "recent",
    price: "lots",
});
console.log(beemer instanceof BmwSpecial); // true, would be false with the earlier version