<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">Le 6 févr. 2015 à 18:04, Ben Newman <<a href="mailto:benjamin@cs.stanford.edu" class="">benjamin@cs.stanford.edu</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">The specific line in rev32 of the spec that prevents [[Call]]ing "classConstructor" functions is <a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects-call-thisargument-argumentslist" target="_blank" class="">9.2.2.2</a>:<br class=""><br class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div class=""><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">2. If </span><i style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">F</i><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">’s [[FunctionKind]]</span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-internal-methods-and-internal-slots" style="font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;text-decoration:none;color:rgb(51,51,187);background-color:rgb(253,253,252)" class="">internal slot</a><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">is "</span><code style="line-height:22.9500007629395px;color:rgb(85,85,85);font-weight:bold;font-family:'Courier New',monospace;white-space:nowrap;background-color:rgb(253,253,252)" class="">classConstructor</code><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">", throw a</span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><b style="font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;color:rgb(85,85,85);background-color:rgb(253,253,252)" class="">TypeError</b><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">exception.</span></div></blockquote><div class=""><br class=""></div><div class="">From my reading of the spec, I think the idiomatic <font face="monospace, monospace" class="">Foo.call(this)</font> pattern that Luke Scott described would work if we simply changed that line to something slightly weaker:</div><div class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""><br class="">2. If </span><i style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">F</i><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">’s [[FunctionKind]]</span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-internal-methods-and-internal-slots" style="color:rgb(51,51,187);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;text-decoration:none;background-color:rgb(253,253,252)" class="">internal slot</a><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">is "</span><code style="line-height:22.9500007629395px;color:rgb(85,85,85);font-weight:bold;font-family:'Courier New',monospace;white-space:nowrap;background-color:rgb(253,253,252)" class="">classConstructor</code><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">" and</span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-instanceofoperator" style="text-decoration:none;color:rgb(51,51,187);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">InstanceofOperator</a><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">(</span><i style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">thisArgument</i><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">, </span><i style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">F</i><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">)</span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> is <b class="">false,</b> throw a</span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><b style="font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;color:rgb(85,85,85);background-color:rgb(253,253,252)" class="">TypeError</b><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class=""> </span><span style="color:rgb(51,51,51);font-family:Cambria,'Palatino Linotype',Palatino,'Liberation Serif',serif;line-height:22.9500007629395px;background-color:rgb(253,253,252)" class="">exception.</span></blockquote></div><div class=""><br class=""></div><div class="">This mirrors an assertion discipline that has saved me from many bugs due to forgetting the <font face="monospace, monospace" class="">new</font> operator:</div><div class=""><br class=""></div><div class=""><blockquote style="margin:0 0 0 40px;border:none;padding:0px" class=""><font face="monospace, monospace" class="">function Base() {<br class="">  <b class="">assert.ok(this instanceof Base);</b><br class="">  ...<br class="">}<br class=""><br class="">function Derived() {<br class="">  <b class="">assert.ok(this instanceof Derived);</b><br class="">  Base.call(this);<br class="">  ...<br class="">}<br class=""><br class="">Derived.prototype = Object.create(Base.prototype, {<br class="">  constructor: { value: Derived, ... }<br class="">});</font></blockquote></div><div class=""><br class=""></div><div class="">Is the addition of the <font face="monospace, monospace" class="">instanceof</font> check naive? Would it invalidate any of the assumptions involved in the invocation of F?</div><div class=""><br class=""></div><div class="">I'm happy to file a bug if this change merits further consideration.</div><div class=""><br class=""></div><div class="">It may be worth noting that only constructors created by <font face="monospace, monospace" class="">class</font> 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 <font face="monospace, monospace" class="">class</font> syntax in order to know whether the <font face="monospace, monospace" class="">Foo.call(this)</font> pattern is safe.</div></div></div></blockquote><br class=""></div><div><div>The issue is deeper. In short, you cannot feed an ES6-class constructor with an already allocated object, whatever that object is.</div><div><br class=""></div><div>With a user-defined good ol' pre-ES6 constructor:</div><div><div><br class=""></div><div>    foo = new Foo // allocate a Foo object and initialise it</div><div>    </div><div>is usually equivalent to:</div><div><br class=""></div><div>    foo = Object.create(Foo.prototype) // allocate a Foo object ...</div><div>    Foo.call(foo) // ... and initilise it</div><div><br class=""></div><div>With the new ES6-class semantics, for the sake of subclassability of builtins, it is, on purpose, not possible to separate allocation from initialisation that way. Even before ES6, builtin classes, did not support such a pattern, e.g.,</div><div><br class=""></div><div>    arr = new Array(2, 3) // allocate a new array and initialise it</div><div><br class=""></div><div>is in no way equivalent to:</div><div><br class=""></div><div>    arr = Object.create(Array.prototype) // allocate an new object, but it won't be an array...</div><div>    Array.call(arr, 2, 3) // ... and don't initialise it, but create uselessly a new Array</div><div>    </div><div>And it appeared that introducing the possibility for builtins to have separate allocation and initialisation phases was problematic.</div><div><br class=""></div><div>—Claude</div><div class=""><br class=""></div></div></div><br class=""></body></html>