Ben Newman (2015-02-06T17:04:30.000Z)
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:

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150206/607ebf64/attachment-0001.html>
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.