<div dir="ltr">In which engine did you try this? Please refer to <a href="http://kangax.github.io/compat-table/es6/">http://kangax.github.io/compat-table/es6/</a> under "Subclassing" to see if your browser supports subclassing builtins yet.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 30, 2016 at 11:32 PM, Gray Zhang <span dir="ltr"><<a href="mailto:otakustay@gmail.com" target="_blank">otakustay@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Recently I encountered an issue about subclassing Error and instance operator, my simplified code is:<div><br></div><div>```</div><div>class MyError extends Error {</div><div>  constructor() {</div><div>    super('my error');</div><div>  }</div><div>}</div><div><br></div><div>let error = new MyError();</div><div>console.log(error instanceof MyError);</div><div>console.log(error.constructor);</div><div>```</div><div><br></div><div>Surprisingly the output is `false` and `function Error() { [native code] }`</div><div><br></div><div>I dived into the ECMAScript 2015 spec and find the behavior is correct, chapter 12.3.5.1 says:</div><div><div style="margin-left:0px;margin-top:0.9em;color:rgb(51,51,51);font-family:cambria,'palatino linotype',palatino,'liberation serif',serif;font-size:17px;line-height:22.95px;background-color:rgb(253,253,252)"><span style="font-family:'times new roman',times,freeserif,serif;font-style:italic;margin-left:0px">SuperCall</span><span> </span><span style="font-weight:bold;margin-left:5pt">:</span><span> </span><code style="color:rgb(85,85,85);font-weight:bold;font-family:'courier new',monospace;white-space:nowrap;margin-left:5pt">super</code><span> </span><span style="font-family:'times new roman',times,freeserif,serif;font-style:italic;margin-left:5pt">Arguments</span></div><ol style="margin-top:0.5em;color:rgb(51,51,51);font-family:cambria,'palatino linotype',palatino,'liberation serif',serif;font-size:17px;line-height:22.95px;background-color:rgb(253,253,252)"><li style="list-style-type:decimal">Let<span> </span><i>newTarget</i><span> </span>be<span> </span><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getnewtarget" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">GetNewTarget</a>().</li><li style="list-style-type:decimal">If<span> </span><i>newTarget</i><span> </span>is<span> </span><b style="color:rgb(85,85,85)">undefined</b>, throw a<span> </span><b style="color:rgb(85,85,85)">ReferenceError</b><span> </span>exception.</li><li style="list-style-type:decimal">Let<span> </span><i>func</i><span> </span>be<span> </span><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getsuperconstructor" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">GetSuperConstructor</a>().</li><li style="list-style-type:decimal"><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">ReturnIfAbrupt</a>(<i>func</i>).</li><li style="list-style-type:decimal">Let<span> </span><i>argList</i><span> </span>be ArgumentListEvaluation of<span> </span><i>Arguments</i>.</li><li style="list-style-type:decimal"><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">ReturnIfAbrupt</a>(<i>argList</i>).</li><li style="list-style-type:decimal">Let<span> </span><i>result</i><span> </span>be<span> </span><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-construct" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">Construct</a>(<i>func</i>,<span> </span><i>argList</i>,<span> </span><i>newTarget</i>).</li><li style="list-style-type:decimal"><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">ReturnIfAbrupt</a>(<i>result</i>).</li><li style="list-style-type:decimal">Let<span> </span><i>thisER</i><span> </span>be<span> </span><a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getthisenvironment" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">GetThisEnvironment</a>( ).</li><li style="list-style-type:decimal">Return<span> </span><i>thisER</i>.<a href="http://www.ecma-international.org/ecma-262/6.0/index.html#sec-bindthisvalue" style="text-decoration:none;color:rgb(51,51,187)" target="_blank">BindThisValue</a>(<i>result</i>).</li></ol></div><div>Since Error can be called as a function without new operator, the result of step 7 is an error instance rather than undefined, so this error instance becomes `this` value of `thisER` and then returned as the result of new MyError constructor.</div><div><br></div><div>The problem is, the spec also said "The Error constructor is designed to be subclassable." so I think instanceof should work correctly on subclasses, however it fails now.</div><div><br></div><div>This also comes to Map, Set, Array and Object constructors.</div><div><br></div><div>Babel 6.7.7 has the correct behavior which fails on instanceof operator but it really introduces some troubles, is this by design and how could I avoid such issues?</div></div>
<br>_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
<br></blockquote></div><br></div>