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个主要抽象方法