ECMAScript 6是否有抽象类约定? [重复]

时间:2022-09-25 12:24:01

This question already has an answer here:

这个问题在这里已有答案:

I was surprised that I couldn't find anything about abstract classes when reading up on ES6. (By "abstract class" I'm talking about the Java meaning of it, in which an abstract class declares method signatures that a subclass must implement in order to be instantiable).

我很惊讶在阅读ES6时我找不到关于抽象类的任何内容。 (通过“抽象类”我在谈论它的Java含义,其中抽象类声明了子类必须实现的方法签名才能实现可实现化)。

Does anyone know of any conventions that have taken hold to implement abstract classes in ES6? It would be nice to be able to catch an abstract class violation with static analysis.

有没有人知道在ES6中实现抽象类的任何约定?能够通过静态分析捕获抽象类违规会很好。

If I were to raise an error at runtime to signal an attempt at abstract class instantiation, what would the error be?

如果我在运行时提出错误来表示尝试抽象类实例化,那么错误是什么?

1 个解决方案

#1


209  

ES2015 does not have Java-style classes with built-in affordances for your desired design pattern. However, it has some options which may be helpful, depending on exactly what you are trying to accomplish.

ES2015没有Java风格的类,内置了适合您所需设计模式的功能。但是,它有一些可能有用的选项,具体取决于您要完成的内容。

If you would like a class that cannot be constructed, but whose subclasses can, then you can use new.target:

如果您想要一个无法构造但可以构造其子类的类,那么您可以使用new.target:

class Abstract {
  constructor() {
    if (new.target === Abstract) {
      throw new TypeError("Cannot construct Abstract instances directly");
    }
  }
}

class Derived extends Abstract {
  constructor() {
    super();
    // more Derived-specific stuff here, maybe
  }
}

const a = new Abstract(); // new.target is Abstract, so it throws
const b = new Derived(); // new.target is Derived, so no error

For more details on new.target, you may want to read this general overview of how classes in ES2015 work: http://www.2ality.com/2015/02/es6-classes-final.html

有关new.target的更多详细信息,您可能需要阅读有关ES2015中的类如何工作的概述:http://www.2ality.com/2015/02/es6-classes-final.html

If you're specifically looking for requiring certain methods be implemented, you can check that in the superclass constructor as well:

如果您特别想要实现某些方法,那么您也可以在超类构造函数中检查它:

class Abstract {
  constructor() {
    if (this.method === undefined) {
      // or maybe test typeof this.method === "function"
      throw new TypeError("Must override method");
    }
  }
}

class Derived1 extends Abstract {}

class Derived2 extends Abstract {
  method() {}
}

const a = new Abstract(); // this.method is undefined; error
const b = new Derived1(); // this.method is undefined; error
const c = new Derived2(); // this.method is Derived2.prototype.method; no error

#1


209  

ES2015 does not have Java-style classes with built-in affordances for your desired design pattern. However, it has some options which may be helpful, depending on exactly what you are trying to accomplish.

ES2015没有Java风格的类,内置了适合您所需设计模式的功能。但是,它有一些可能有用的选项,具体取决于您要完成的内容。

If you would like a class that cannot be constructed, but whose subclasses can, then you can use new.target:

如果您想要一个无法构造但可以构造其子类的类,那么您可以使用new.target:

class Abstract {
  constructor() {
    if (new.target === Abstract) {
      throw new TypeError("Cannot construct Abstract instances directly");
    }
  }
}

class Derived extends Abstract {
  constructor() {
    super();
    // more Derived-specific stuff here, maybe
  }
}

const a = new Abstract(); // new.target is Abstract, so it throws
const b = new Derived(); // new.target is Derived, so no error

For more details on new.target, you may want to read this general overview of how classes in ES2015 work: http://www.2ality.com/2015/02/es6-classes-final.html

有关new.target的更多详细信息,您可能需要阅读有关ES2015中的类如何工作的概述:http://www.2ality.com/2015/02/es6-classes-final.html

If you're specifically looking for requiring certain methods be implemented, you can check that in the superclass constructor as well:

如果您特别想要实现某些方法,那么您也可以在超类构造函数中检查它:

class Abstract {
  constructor() {
    if (this.method === undefined) {
      // or maybe test typeof this.method === "function"
      throw new TypeError("Must override method");
    }
  }
}

class Derived1 extends Abstract {}

class Derived2 extends Abstract {
  method() {}
}

const a = new Abstract(); // this.method is undefined; error
const b = new Derived1(); // this.method is undefined; error
const c = new Derived2(); // this.method is Derived2.prototype.method; no error