[英]Creating multiple abstract classes javascript ES6
今天,我想到了一个使用Proxy对象的想法,以允许创建多个抽象类,例如
const abstract = abstractClass => new Proxy(abstractClass,{
construct: (target, args) => { throw new Error('Error, class was declared as abstract!') }
});
class A{}
class B{}
class C{}
[A,B,C] = [A,B,C].map(c => abstract(c));
所以我的问题是这种解决方案是否有缺点,如果有的话,它们是什么。
缺点是Proxy
不能可靠地在ES5中进行多填充,并且速度很慢。
一个好的方法就是用继承来解决这个问题:
class Abstract {
constructor() {
if (Object.getPrototypeOf(this.constructor) === Abstract
|| this.constructor === Abstract) {
throw new Error("Cannot instantiate abstract class");
}
}
};
class AbstractFoo extends Abstract {...}
class ConcreteFoo extends AbstractFoo {...}
直接实例化Abstract
和AbstractFoo
将引发错误。
ES.next装饰器可用于简化任务:
function abstract(target) {
return class Abstract extends target {
constructor(...args) {
super(...args);
if (this.constructor === Abstract) {
throw new Error("Cannot instantiate abstract class");
}
}
};
}
@abstract
class AbstractFoo {...}
class ConcreteFoo extends AbstractFoo {...}
由于装饰器基本上是辅助函数,因此可以直接在纯ES6中应用:
const AbstractFoo = abstract(class AbstractFoo {...});
class ConcreteFoo extends AbstractFoo {...}
请注意,在装饰器的情况下,将在抛出错误之前对原始构造器进行评估,这是使用extends
的代价。 解决方法是使用函数而不是类,并手动从target
继承它,类似于TypeScript __extends
和Babel __inherits
帮助函数,这样可以在super()
之前引发错误。 另一个解决方法是使用new.target
(当前无法使用Babel转换为ES5):
function abstract(target) {
return class Abstract extends target {
constructor(...args) {
if (new.target === Abstract) {
throw new Error("Cannot instantiate abstract class");
}
super(...args);
}
};
}
一种更干净的方法是使用TypeScript(如注释中所建议),它引入抽象类作为语言功能,并在设计时进行处理。 这允许不污染原型链。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.