Ben Newman (2015-02-06T17:04:30.000Z)
d at domenic.me (2015-02-17T18:12:17.754Z)
The specific line in rev32 of the spec that prevents [[Call]]ing "classConstructor" functions is [9.2.2.2](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist): 2 If *F*’s [[FunctionKind]] [internal slot](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-internal-methods-and-internal-slots) 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](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-internal-methods-and-internal-slots) is "classConstructor" and [InstanceofOperator](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-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: ```js 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. 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.
d at domenic.me (2015-02-17T18:12:04.511Z)
The specific line in rev32 of the spec that prevents [[Call]]ing "classConstructor" functions is [9.2.2.2](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist): \2. If *F*’s [[FunctionKind]] [internal slot](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-internal-methods-and-internal-slots) 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](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-internal-methods-and-internal-slots) is "classConstructor" and [InstanceofOperator](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-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: ```js 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. 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.