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