Subclassing ES6 objects with ES5 syntax.

C. Scott Ananian ecmascript at cscott.net
Wed Apr 29 19:40:04 UTC 2015


On Wed, Apr 29, 2015 at 3:32 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>
wrote:

> On Apr 29, 2015, at 12:24 PM, C. Scott Ananian wrote:
>
> On Wed, Apr 29, 2015 at 3:09 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>
> wrote:
>
>>  class DefensivePromise extends Promise {
>>   constructor(x) {
>>     super(x);
>>     if (new.target === DefensivePromise) {
>>
>            // I'm assuming this test is just to be subclass friendly and
> allow subclasses to freeze later?
>
>>       Object.freeze(this);
>>     }
>>   }
>>   static resolve(x) {
>>     switch (true) {
>>        default:
>>
>          // I guess a do { } while(false); would work as well?
>
>>           // assuming frozen primordial
>>           if (x.constructor !== DefensivePromise) break;  //just a quick
>> exit, doesn't guarantee much
>>           if (!Object.isFrozen(x)) break;
>>           If (Object.getOwnPropertyDescriptor(x, 'then')) break;
>>           //a more subclass friendly approach would walk x's
>> [[Prototype]] chain to ensure that the correct 'then' is inherited from
>> frozen prototypes
>>           if (Object.getPrototypeOf(x) !== DefensivePromise.prototype)
>> break;
>>           //Assert: x.then === Promise.prototype.then, now and forever
>> after
>>           return x;
>>      }
>>      // must be called on a subclass of DefensivePromise, so we don't
>> need to enforce the 'then' invariant
>>      If  (x.constructor ===  this) return x;   //in which case a
>> constructor check is good enough
>>
>           // ^^ this is a mistake right?  I think this line doesn't
> belong.
>
>>      return new this(r => {r(x)});
>>    }
>>  }
>> Object.freeze(DefensivePromise);
>> Object.freeze(DefensivePromise.prototype);
>>
>
> It's not clear what the `x.constructor` test is still doing in your
> implementation.
>
>
> Do you mean the first or second occurrence?
>

The second occurrence.  At that point all we know about x is that it's
*not* something safe.  We shouldn't be looking at `constructor` in that
case.


> But, regardless of the details of our implementations, can we agree that
> "tamper proof" promises don't seem to need the [[PromiseConstructor]]
> property?
>
>
> I agree with you, but I'm not the Promise champion.
>
> Regardless, too late for ES2015.  It will have to proposed as an ES2016
> change.
>

True, but since subclassable Promises haven't been implemented in the major
engines yet, still in time to get everyone to agree to implement the new
semantics before use "in the wild" locks in the warts of ES2015.

If we get consensus, I can certainly ensure that es6-shim, core-js, and
babel implement the "ES2016" semantics.
  --scott
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150429/1ea0eadb/attachment-0001.html>


More information about the es-discuss mailing list