Frontend Mayhem

Javascript: instanceof operator

May 22, 2017

In the previous blog post, we looked at using the typeof operator to infer types of primitive values. In this blog post, we will look at typeof’s distant cousin, the instanceof operator.

instanceof

instanceof uses the prototype of an object to determine if it’s an instance of a class or a constructed function.

obj instanceof datatype

In the code above, the instanceof operator checks if datatype.prototype is anywhere in the prototype chain of obj. Therefore, it is possible for a single object to be an instance of multiple classes.

[] instanceof Array  //true

[] instanceof Object //true because Array.prototype is an instanceof Object

Checking custom types

instanceof really shines when working with custom types. Coincidentally, this is the same area where typeof operator concedes defeat.

const Animal = function(type) {
  this.type = type;
}

const dog = new Animal('dog');
dog instanceof Animal; //returns true
dog instanceof Object; //returns true
typeof dog;            //returns 'object'. Not very useful

Caveats

Like most things in the life of a JavaScript developer, instanceof comes with it’s own baggage.

Protoype-less Object

Object.create can be used to create objects without a prototype, which is a sure fire way to defeat the instanceof object.

const obj = Object.create(null);
Object.getPrototypeOf(obj); //returns null
obj instanceof Object       //returns false
typeof obj;                 //returns "object"

In this case, obj is an object that isn’t an instance of the Object class.

Prototype’s can be changed

The outcome of an instanceof test can be influenced by changing the prototype property of the constructor or the object’s prototype.

const Animal = function(type) {
  this.type = type;
}

const Dog = new Animal('dog');

Animal.prototype = {};

Dog instanceof Animal; //returns false

Primitive’s & literal notation

In the blog post about the typeof operator, we established that it is best suited to test types of primitive values.

Let’s look at a few examples of how instanceof handles primitive values.

const literalStr = 'Literal String';
const str = new String('Test String');

literalStr instanceof String; //returns false
literalStr instanceof Object; //returns false

str instanceof String;        //returns true
str instanceof Object;        //returns true

Unless you use a constructor to define such values, you’re out of luck with the instanceof operator. The only exception to this is object literal notation.

{} instanceof Object; //returns true

Watandeep Sekhon

Written by Watandeep Sekhon.
Website / Twitter / LinkedIn / Instagram