# JS Tip of the Day: Symbol.hasInstance

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-symbol-hasinstance/643102>\
**Category:** web dev\
**Created:** [May 4, 2020, 12:29pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-symbol-hasinstance/643102 "2020-05-04T12:29:31Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [May 4, 2020, 12:29pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-symbol-hasinstance/643102/1 "2020-05-04T12:29:31Z")

</div>

**Symbol.hasInstance**  
Version: ES2015  
Level: Advanced

By default, the `instanceof` operator checks an object to see if it belongs to a constructor by checking the prototype chain of the object. If the prototype chain has an object matching the `prototype` property of the constructor, `instanceof` returns true.

```javascript
let array = new Array();
console.log(array instanceof Array); // true
console.log(array instanceof Object); // true

let object = new Object();
console.log(object instanceof Array); // false
console.log(object instanceof Object); // true

```

This behavior can be customized using `Symbol.hasInstance`. When a constructor implements a static `Symbol.hasInstance`, that will be used to determine whether or not an object called with `instanceof` is an instance of that constructor overriding the standard prototype check.

```javascript
class Faker {
    static [Symbol.hasInstance] (instance) {
        return instance.fakable;
    }
}
let normal = {};
let faked = { fakable: true };
console.log(normal instanceof Faker); // false
console.log(faked instanceof Faker); // true

```

One thing to be careful of is, because the `Symbol.hasInstance` method replaces the normal check, it could also return false positives; if an instance was actually created by a certain constructor, `instanceof` might not reflect that.

```javascript
class Faker {
    static [Symbol.hasInstance] (instance) {
        return instance.fakable;
    }
}
let fakedFaker = new Faker();
console.log(fakedFaker instanceof Faker); // false

```

If you want access to the default behavior, you can call the `Symbol.hasInstance` method of `Function.prototype`. This way, if you want to fallback to the default behavior when your custom check fails, you have the option to do so.

```javascript
class Faker {
    static [Symbol.hasInstance] (instance) {
        let origHas = Function.prototype[Symbol.hasInstance];
        return instance.fakable || origHas.call(this, instance);
    }
}
let fakedFaker = new Faker();
console.log(fakedFaker instanceof Faker); // true

```

`Symbol.hasInstance` can be useful with mixins. If your mixin is defined by a constructible function, that function can be used with `instanceof` to determine whether or not the mixin was applied to an instance used with `instanceof`

```javascript
let eaterMixin = Symbol('eaterMixin');
function eater (base) {
    return class extends base {
        constructor (...args) {
            super(...args);
            this[eaterMixin] = true;
        }
        eat () {
            console.log('Nom nom');
        }
    }
}
Object.defineProperty(eater, Symbol.hasInstance, {
    value (instance) {
        return eaterMixin in instance;
    }
});

```

```javascript
class Hippo {}
let EatingHippo = eater(Hippo);

let hungryHippo = new Hippo();
let chonkyHippo = new EatingHippo();
chonkyHippo.eat(); // Nom nom

console.log(hungryHippo instanceof Hippo); // true
console.log(hungryHippo instanceof eater); // false
console.log(chonkyHippo instanceof Hippo); // true
console.log(chonkyHippo instanceof eater); // true

```

Here, the `eater` mixin adds a symbol property to each instance it creates which is then used with the `Symbol.hasInstance` check. If that symbol doesn’t exist, its not an “instance of” the mixin.

Note that a symbol doesn’t have to be used for this check. You could also do something else to identify the mixin, such as check to see if the instance has the methods/properties defined by the mixin. Symbols are useful in that they’re unique and mostly non-intrusive.

Also worth noting is that to set `Symbol.hasInstance`, `Object.defineProperty()` was necessary because the default `Symbol.hasInstance` in `Function.prototype` is defined as not writable. Because of this a normal assignment would not work. Using define on the instance ignores the writable characteristic in the inherited value.

More info:

- [Symbol.hasInstance on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance)
