Symbol.hasInstance and [[Get]] vs [[GetOwnProperty]]

Claude Pache claude.pache at gmail.com
Tue Aug 16 12:31:31 UTC 2016


Your mileage may vary, but for me it is, on contrary, intuitive that a subclass inherits by default all the methods of its superclass, without arbitrary exceptions such as `[Symbol.hasInstance]()`.

Whether it is desirable, I am sure it depends on what you put in the `[Symbol.hasInstance]()` method. But the situation for that particular method is the same as for any random method: a superclass must be careful if it wants to be subclass-friendly.

—Claude

> Le 16 août 2016 à 03:48, /#!/JoePea <joe at trusktr.io> a écrit :
> 
> I want to add also that using `super` makes it more readable, but still requires boilerplate code, and is just as statically limited as using a direct reference to a constructor ([I wish it wasn't](https://esdiscuss.org/topic/the-super-keyword-doesnt-work-as-it-should) <https://esdiscuss.org/topic/the-super-keyword-doesnt-work-as-it-should)>):
> 
> ```js
> class A {
>     static [Symbol.hasInstance](obj) {
>         if (this === A) return false
>         else return super[Symbol.hasInstance](obj)
>     }
> }
> ```
> 
> /#!/JoePea
> 
> On Mon, Aug 15, 2016 at 6:45 PM, /#!/JoePea <joe at trusktr.io <mailto:joe at trusktr.io>> wrote:
> It seems like using [[Get]] for looking up `@@hasInstance` can be confusing and requires devs to write extra code. For example, suppose we have the following code:
> 
> ```js
> class A {
>     static [Symbol.hasInstance] (obj) {
>         return false
>     }
> }
> 
> class B extends A {}
> class C extends B {}
> 
> let c = new C
> 
> console.log(c instanceof B) // false, but expected true!
> console.log(c instanceof A) // false, as expected
> ```
> 
> The `c instanceof B` check (arguably unintuitively) fails. Defining a `Symbol.hasInstance` method on a base class causes `instanceof` checks on any subclasses to automatically fail unless the developer takes care to write an ugly and fragile workaround:
> 
> ```js
> class A {
>     static [Symbol.hasInstance](obj) {
>         if (this === A) return false
>         else return Function.prototype[Symbol.hasInstance].call(this, obj)
>     }
> }
> 
> class B extends A {}
> class C extends B {}
> 
> let c = new C
> 
> console.log(c instanceof B) // true, as expected
> console.log(c instanceof A) // false, as expected
> ```
> 
> That seems likely to introduce errors or headaches.
> 
> What if the lookup for `Symbol.hasInstance` on an object use [[GetOwnProperty]]? Then the first version without the conditional checks would not break subclasses.
> 
> /#!/JoePea
> 
> _______________________________________________
> 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/20160816/b692512a/attachment.html>


More information about the es-discuss mailing list