ECMAScript 6 是不是有抽象类的约定? [复制]

Posted

技术标签:

【中文标题】ECMAScript 6 是不是有抽象类的约定? [复制]【英文标题】:Does ECMAScript 6 have a convention for abstract classes? [duplicate]ECMAScript 6 是否有抽象类的约定? [复制] 【发布时间】:2015-06-11 09:35:10 【问题描述】:

我很惊讶在阅读 ES6 时找不到任何关于抽象类的信息。 (我所说的“抽象类”是指它的 Java 含义,其中抽象类声明子类必须实现的方法签名才能实例化)。

有谁知道在 ES6 中实现抽象类的任何约定?如果能够通过静态分析捕获抽象类违规,那就太好了。

如果我在运行时引发错误以表示尝试抽象类实例化,那么错误会是什么?

【问题讨论】:

ES6 不会改变早期 javascript 版本的基本原型继承机制。 “抽象类”的概念在 JavaScript 术语中并没有多大意义,尽管预处理器类型语言当然可以实现这样的东西。 由于 javascript 不是强类型的抽象类不会有用。 抽象类,以及特征和混合,是一个待定的"strawman"proposal。 @gorgi93 - 抽象类与强类型无关。自 1970 年代以来,像 Smalltalk 这样的动态类型语言就有抽象类(按照惯例)。 (晚会)我同意你的观点,这不是一个重复的问题。即使它是同一只野兽,它也会经常被问到。 JS 类有点类似于 ruby​​ 的类。如果没有实现,我使用类似的方法抛出错误,但不检查实例化(许多 ruby​​ 开发人员也这样做)。在我看来,这是清晰的代码。创建一个 NotImplementedClass (second answer)。然后在你的基类mymethod()throw new NotImplementedError() 【参考方案1】:

ES2015 没有 Java 风格的类,这些类为您想要的设计模式提供内置功能。但是,它有一些可能会有所帮助的选项,具体取决于您要完成的工作。

如果你想要一个无法构造的类,但它的子类可以,那么你可以使用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

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

如果您特别希望实现某些方法,您也可以在超类构造函数中检查:

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)这是一个不同的问题,2)另一个问题的公认答案是我的问题的错误答案,3)我的问题首先被问到。我看到 AWB 的答案(对另一个问题)在此处回答了我的问题,但未标记为已接受的答案。 刚刚发现 Safari 不支持new.target。转译后的代码抛出:SyntaxError: Unexpected token '.' new.target 在 2016 年 4 月 29 日的最新 babel 中得到支持:github.com/babel/babel-eslint/issues/235 @siannone MDN 说 safari 支持 new.target developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 如果你写 throw new TypeError("Cannot constructor " + new.target.name + " instances directly");它将变得对重构更加友好。

以上是关于ECMAScript 6 是不是有抽象类的约定? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

抽象类

Android ContentProvider类的6个主要抽象方法

ECMAScript 6 引入的 JavaScript 类(class)--类同java class

C#类命名约定:是基类还是基于类还是抽象类

javascript开发模式

ECMAScript 6 或 7 中是不是支持静态类型?