Subclassing ES6 objects with ES5 syntax.

C. Scott Ananian ecmascript at
Sat Apr 25 21:04:21 UTC 2015

Inadvertently moved discussion off-list; requoting on list:

On Sat, Apr 25, 2015 at 4:33 PM, Domenic Denicola <d at> wrote:

> From: es-discuss [mailto:es-discuss-bounces at] On Behalf Of C.
> Scott Ananian
> > But in the code given previously, I've used `Object.setPrototypeOf` to
> effectively change the type of the object -- but [[PromiseConstructor]]
> doesn't follow along.
> That is exactly the kind of tampering that the unforgable
> [[PromiseConstructor]] mechanism is meant to prevent.

Sure, but why? If it is now quacking like a duck, returning it from
GoosePromise.resolve as if it were still a goose seems wrong.

> Because then you could break invariants by doing e.g. `var syncThenable =
> { then(f) { f(5); }; syncThenable.constructor = Promise`.

Oh, I don't think looking at the constructor is right, either.  It seems
you should perhaps be looking at the object's prototype chain instead, like
instanceof does.

The invariant I expect to be preserved is that `GoosePromise.resolve(x)`
gives me a `GoosePromise` back, regardless of what sort of `x` I give it.
But instead if I give it an `x` which *used to be* a goose but is now a
duck, I get back a duck instead of a goose.

And this is a real use case: my `prfun` package creates a `BoundPromise`
subclass, but because I'm doing it ES5 style without access to
``, `Promise.resolve(x)` returns a `BoundPromise` (and
`BoundPromise.resolve(x)` returns a `Promise`) because everything "was once
a Promise".

This particular case will probably be less frequent once we can do "real"
subclassing in JavaScript engines... but it still seems to indicate to me
that this basic idea is broken.  What things "once were" seems to be some
weird property with no resemblance to what they are now.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list