d at domenic.me (2015-02-17T18:14:34.364Z)
On Feb 6, 2015, at 9:04 AM, Ben Newman wrote: > 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 some TC39 members wanted to future proof for things they want to experiment with for future editions. These things may include: 1. Some way 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 constructor 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
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>