Subclassing native class and instanceof operator

Logan Smyth loganfsmyth at gmail.com
Tue May 31 07:25:15 UTC 2016


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

On Mon, May 30, 2016 at 11:56 PM, Gray Zhang <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>于2016年5月31日周二 下午2:47写道:
>
>> In which engine did you try this? Please refer to
>> 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> 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
>>>
>>>    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?
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160531/af2eeb72/attachment-0001.html>


More information about the es-discuss mailing list