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