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

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to