2017-10-14 70 views
2

通常使用ES6類,它是很容易複合類,如如何正確子類的承諾與巴貝爾和ES6

class A extends B { /*...*/ } 

當涉及到本地,內置樣的承諾,雖然很多文章建議避免子類的類。巴貝爾本身顯然無法運輸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

本地支持承諾的大多數瀏覽器也支持ES6類,所以您可能根本不應該對它們進行傳輸。 – Bergi

+1

只是好奇,爲什麼你想子類'承諾'?我從來沒有見過它的好用例。 – Bergi

+0

你想達到什麼目的? – guest271314

回答

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以便從其他功能中受益。