Subclassing ES6 objects with ES5 syntax.

C. Scott Ananian ecmascript at
Wed Apr 29 17:02:26 UTC 2015

On Wed, Apr 29, 2015 at 12:49 PM, Allen Wirfs-Brock <allen at>

> On Apr 29, 2015, at 8:44 AM, C. Scott Ananian wrote:
On Wed, Apr 29, 2015 at 1:06 AM, Brendan Eich <brendan at> wrote:
> Kevin Smith wrote:
>>> So what would the ideal Promise.resolve semantics do?  I'm not sure,
>>> maybe use SpeciesConstructor instead of [[PromiseConstructor]]?
>> This removes the wart in my view, has no less integrity. C. Scott?
> Making this concrete, here would be the new text for
> Promise.resolve(x):
>> The resolve function returns either a new promise resolved with the
>> passed argument, or the argument itself if the argument is a promise
>> produced by this constructor.
>> 1. Let C be the this value.
>> 2. If IsPromise(x) is true,
>>     a. Let constructor be the value of SpeciesConstructor(x, %Promise%)
>     b. If SameValue(constructor, C) is true, return x.
>> 3. If Type(C) is not Object, throw a TypeError exception.
>> 4. Let S be Get(C, @@species).
>> 5. ReturnIfAbrupt(S).
>> 6. If S is neither undefined nor null, let C be S.
>> 7. Let promiseCapability be NewPromiseCapability(C)
> [...remainer elided...]
> Step 2a is the only change.  (It was previously "Let constructor be the
> value of x's [[PromiseConstructor]] internal slot.")
> But SpeciesConstructor (or any access to x's @@species) goes through
> `x.constructor` and my recollection is that the motivation for adding
> [[PromiseConstructor]] was that 'constructor'  was not sufficiently tamper
> proof.  From that perspective, it seems that SpeciesConstructor is actually
> worse than just accessing `x.constructor`.
> Also, in a private message Mark Miller mentioned that the primarily
>  security invariant he's concerned about really relates to the behavior of
> the `then` method of the object returned by `Promise.resolve(x)`.  Neither
> testing `construct` or SpeciesConstructor really tells you anything about
> `then`.   It seems that the root problem here is trying to apply nominal
> type based reasoning to JS.

I agree that is the root problem.  That is why [[PromiseConstructor]] is
misguided, as (in their own way) is testing x.[[Prototype]] and testing
x.then.  We could imagine rewriting step 2 to test all three of these. And
then maybe we should think about proxies as well!  But rather than add some
complicated test to try to do something which doesn't actually accomplish
its purpose, better to use the simple/expected/consistent thing, which
seems (at this point) to be SpeciesConstructor.   And that seems to make
setting Promise.@@species "work right" as well, for what that's worth.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list