Subclassing native class and instanceof operator

Gray Zhang otakustay at gmail.com
Tue May 31 06:32:15 UTC 2016


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

   1. Let *newTarget* be GetNewTarget
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getnewtarget>
   ().
   2. If *newTarget* is *undefined*, throw a *ReferenceError* exception.
   3. Let *func* be GetSuperConstructor
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getsuperconstructor>
   ().
   4. ReturnIfAbrupt
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt>
   (*func*).
   5. Let *argList* be ArgumentListEvaluation of *Arguments*.
   6. ReturnIfAbrupt
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt>
   (*argList*).
   7. Let *result* be Construct
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-construct>
   (*func*, *argList*, *newTarget*).
   8. ReturnIfAbrupt
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-returnifabrupt>
   (*result*).
   9. Let *thisER* be GetThisEnvironment
   <http://www.ecma-international.org/ecma-262/6.0/index.html#sec-getthisenvironment>(
   ).
   10. 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.

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.

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

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?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160531/35c40e85/attachment.html>


More information about the es-discuss mailing list