From a09e802f51baa7f6dac58cbb98f8c6a285f4a487 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Tue, 27 Apr 2021 16:02:29 +0300 Subject: [PATCH] make `.constructor === Promise` work with polyfilled `Promise` for all native promise-based APIs --- CHANGELOG.md | 2 +- packages/core-js/modules/es.promise.js | 27 ++++++++++++-------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fee673e64255..31d27b5d7065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Changelog ##### Unreleased -- Made `instanceof Promise` work with polyfilled `Promise` for all native promise-based APIs +- Made `instanceof Promise` and `.constructor === Promise` work with polyfilled `Promise` for all native promise-based APIs ##### 3.11.0 - 2021.04.22 - Added [accessible `Object#hasOwnProperty` stage 2 proposal](https://github.com/tc39/proposal-accessible-object-hasownproperty) diff --git a/packages/core-js/modules/es.promise.js b/packages/core-js/modules/es.promise.js index eaafc83bf169..7fed1200a004 100644 --- a/packages/core-js/modules/es.promise.js +++ b/packages/core-js/modules/es.promise.js @@ -33,11 +33,11 @@ var PROMISE = 'Promise'; var getInternalState = InternalStateModule.get; var setInternalState = InternalStateModule.set; var getInternalPromiseState = InternalStateModule.getterFor(PROMISE); +var NativePromisePrototype = NativePromise && NativePromise.prototype; var PromiseConstructor = NativePromise; var TypeError = global.TypeError; var document = global.document; var process = global.process; -var $fetch = getBuiltIn('fetch'); var newPromiseCapability = newPromiseCapabilityModule.f; var newGenericPromiseCapability = newPromiseCapability; var DISPATCH_EVENT = !!(document && document.createEvent && global.dispatchEvent); @@ -284,11 +284,11 @@ if (FORCED) { : newGenericPromiseCapability(C); }; - if (!IS_PURE && typeof NativePromise == 'function') { - nativeThen = NativePromise.prototype.then; + if (!IS_PURE && typeof NativePromise == 'function' && NativePromisePrototype !== Object.prototype) { + nativeThen = NativePromisePrototype.then; - // wrap native Promise#then for native async functions - redefine(NativePromise.prototype, 'then', function then(onFulfilled, onRejected) { + // make `Promise#then` return a polyfilled `Promise` for native promise-based APIs + redefine(NativePromisePrototype, 'then', function then(onFulfilled, onRejected) { var that = this; return new PromiseConstructor(function (resolve, reject) { nativeThen.call(that, resolve, reject); @@ -296,18 +296,15 @@ if (FORCED) { // https://github.com/zloirock/core-js/issues/640 }, { unsafe: true }); - // make `instanceof Promise` work for all native promise-based APIs + // make `.constructor === Promise` work for native promise-based APIs + try { + delete NativePromisePrototype.constructor; + } catch (error) { /* empty */ } + + // make `instanceof Promise` work for native promise-based APIs if (setPrototypeOf) { - setPrototypeOf(NativePromise.prototype, PromiseConstructor.prototype); + setPrototypeOf(NativePromisePrototype, PromiseConstructor.prototype); } - - // wrap fetch result, TODO: drop it in `core-js@4` in favor of workaround above - if (typeof $fetch == 'function') $({ global: true, enumerable: true, forced: true }, { - // eslint-disable-next-line no-unused-vars -- required for `.length` - fetch: function fetch(input /* , init */) { - return promiseResolve(PromiseConstructor, $fetch.apply(global, arguments)); - } - }); } }