有在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
以便從其他功能中受益。
本地支持承諾的大多數瀏覽器也支持ES6類,所以您可能根本不應該對它們進行傳輸。 – Bergi
只是好奇,爲什麼你想子類'承諾'?我從來沒有見過它的好用例。 – Bergi
你想達到什麼目的? – guest271314