Subclassing native class and instanceof operator

Gray Zhang otakustay at gmail.com
Tue May 31 06:56:37 UTC 2016


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


More information about the es-discuss mailing list