traits are now impossible in ES6 until ES7 since rev32?

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Feb 6 12:02:15 PST 2015


On Feb 6, 2015, at 9:04 AM, Ben Newman wrote:

> The specific line in rev32 of the spec that prevents [[Call]]ing "classConstructor" functions is 9.2.2.2:
> 
> 2. If F’s [[FunctionKind]] internal slot is "classConstructor", throw a TypeError exception.
> 
> From my reading of the spec, I think the idiomatic Foo.call(this) pattern that Luke Scott described would work if we simply changed that line to something slightly weaker:
> 
> 2. If F’s [[FunctionKind]] internal slot is "classConstructor" and InstanceofOperator(thisArgument, F) is false, throw a TypeError exception.
> 
> This mirrors an assertion discipline that has saved me from many bugs due to forgetting the new operator:
> 
> function Base() {
>   assert.ok(this instanceof Base);
>   ...
> }
> 
> function Derived() {
>   assert.ok(this instanceof Derived);
>   Base.call(this);
>   ...
> }
> 
> Derived.prototype = Object.create(Base.prototype, {
>   constructor: { value: Derived, ... }
> });
> 
> Is the addition of the instanceof check naive? Would it invalidate any of the assumptions involved in the invocation of F?
> 
> I'm happy to file a bug if this change merits further consideration.

There is nothing about  ES6 classes or subclassing built-ins that inherently requires line 2 above.  Without it, calling a class would work just fine and new.target would even give you a way to distinguish [[Call]] invocation from a [[Construct]] invocation.

Line 2 exists because sone TC39 members wanted to future proof for things they want to experiment with for future editions.  These things may include:
   1) Someway to provide a separate function body that is used when the constructor is [[Call]]'ed 
   2) Allowing unqualified using of 'super()' in "called" constructor to mean the same thing as 'super.constructor()'
   3) (maybe making "calling" a constructor equivalent to "newing" the onstructor

Allowing calls of class constructors would allow people to start writing code that might create legacy issues for such future features.

I think it would take more than a bug to change this now.

> 
> It may be worth noting that only constructors created by class syntax will have their [[FunctionKind]] internal slot set to "classConstructor", so (even with the current spec) you can still invoke ordinary constructor functions using [[Call]]. However, it seems regrettable that you have to know whether a constructor was created by class syntax in order to know whether the Foo.call(this) pattern is safe.

yup

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150206/5472e2c5/attachment.html>


More information about the es-discuss mailing list