Subclassing native class and instanceof operator

Allen Wirfs-Brock allen at wirfs-brock.com
Tue May 31 10:53:00 UTC 2016


> On May 31, 2016, at 3:25 AM, Logan Smyth <loganfsmyth at gmail.com> wrote:
> 
> The correct spec behavior is to return an instance of `MyError`. Step 7 in your example is not equivalent to calling `Error` without `new`, which seems to be your assumption. The `newTarget` parameter passed to `Construct` is used to determine the prototype of the final object, and in this context `newTarget` would be `MyError`.
> 
> Babel does not support extending builtins by default because it is difficult to transpile properly and would add more boilerplate in all class cases, even those which do not require logic to handle native extension. If you need builtin extension support, the only way at the moment is to explicitly enable it via a plugin like https://www.npmjs.com/package/babel-plugin-transform-builtin-extend <https://www.npmjs.com/package/babel-plugin-transform-builtin-extend>
> 
> On Mon, May 30, 2016 at 11:56 PM, Gray Zhang <otakustay at gmail.com <mailto:otakustay at gmail.com>> wrote:
> I know NodeJS outputs `true` in this case, but my problem is from the spec it seems `false` is the correct result, or am I missing some chapters in spec?
> 
> Jordan Harband <ljharb at gmail.com <mailto:ljharb at gmail.com>>于2016年5月31日周二 下午2:47写道:
> In which engine did you try this? Please refer to http://kangax.github.io/compat-table/es6/ <http://kangax.github.io/compat-table/es6/> under "Subclassing" to see if your browser supports subclassing builtins yet.
> 
> On Mon, May 30, 2016 at 11:32 PM, Gray Zhang <otakustay at gmail.com <mailto:otakustay at gmail.com>> wrote:
> Recently I encountered an issue about subclassing Error and instance operator, my simplified code is:
> 
> ```
> class MyError extends Error {
>   constructor() {
>     super('my error’);
>   }
> }
> 
> let error = new MyError();
> console.log(error instanceof MyError);
> console.log(error.constructor);
> ```
> 
> Surprisingly the output is `false` and `function Error() { [native code] }`
> 
> I dived into the ECMAScript 2015 spec and find the behavior is correct, chapter 12.3.5.1 says:
> SuperCall : super Arguments
> Let newTarget be GetNewTarget <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getnewtarget>().
> If newTarget is undefined, throw a ReferenceError exception.
> Let func be GetSuperConstructor <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getsuperconstructor>().
> ReturnIfAbrupt <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt>(func).
> Let argList be ArgumentListEvaluation of Arguments.
> ReturnIfAbrupt <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt>(argList).
> Let result be Construct <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-construct>(func, argList, newTarget).
> ReturnIfAbrupt <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt>(result).
> Let thisER be GetThisEnvironment <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getthisenvironment>( ).
> Return thisER.BindThisValue <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-bindthisvalue>(result).
> 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.


Huh??  Step 7  isn’t a [[Call]] it is a [[Construct]].  Syntactic rules such as “must use new to invoke a constructor” can’t apply at the level of pseudo-code.

> 
> 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.

It is specified to work.  Your implementation must be wrong or imp complete.


> 
> This also comes to Map, Set, Array and Object constructors.

Also should work

Allen

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160531/558a12a9/attachment.html>


More information about the es-discuss mailing list