通常使用ES6类,复合类很容易,比如
class A extends B { /*...*/ }
当谈到像Promises这样的原生内置类时,虽然很多文章都建议避免使用子类化。巴贝尔本身显然无法转变such use cases。是否有可能正确地转换子类或甚至调整下面的例子?
PS我正在使用汇总ES2015 preset,并尝试将transform-builtin-classes与.babelrc
class P extends Promise {
foo(func) {
return this.then(func)
}
static bar(a) {
return a
}
}
答案 0 :(得分:1)
ES5中内置类继承存在障碍,有时可以通过使用Reflect.construct
和Object.setPrototypeOf
的组合作为解决方法来避免。这是Babel transform-builtin-classes
使用的方法。
此方法适用的事实取决于内置类的工作原理。如果是Promise
,则可能需要从内置继承的其他中间类,然后可以使用常规class ... extends
继承它。
function _P(executor) {
return Reflect.construct(Promise, [executor], P);
}
Object.setPrototypeOf(_P, Promise);
_P.prototype = Object.create(Promise.prototype);
class P extends _P {
static bar(arg) {
return new this(resolve => resolve(arg));
}
foo(...fns) {
return this.then(...fns);
}
}
这确定了correct prototype chain。这种方法的缺点是它被硬编码为P
子类,难以进一步扩展。
更简洁的方法是使中间类包装内置类实例。这需要在中间类中复制原始类API,但由于它很小,这对原型链来说是可接受的权衡,没有任何限制:
function _P(executor) {
this._promise = new Promise(executor);
}
Object.setPrototypeOf(_P, Promise);
_P.prototype = Object.assign(
Object.create(Promise.prototype),
{
then(...args) {
return this._promise.then(...args);
},
...
}
);
class P extends _P { ... }
应该注意,此功能已经通过promise ponyfills提供,包括mapSeries
。将它们作为自包含辅助函数使用通常是P
子类的首选替代方法,考虑到每个本机承诺都应转换为P
承诺P.resolve
,以便从其他功能中受益。