In order to make functions more flexible in performance, programmers often try to make them behave differently for various types of values. A good way to check whether the given value belongs to a certain class is by using the instanceof operator.

This operator checks whether there is a specified constructor in the object’s prototype and returns a boolean value, true or false as a result. In some newer versions of the JS standards it can also check if the object is an instance of the specific class.

Instanceof operator

In order to use this operator you need to write the name of the object you want to check, follow it by instanceof statement and then specify the class where you think the object belongs to.

Below is a simple example that illustrates the proper use of the instanceof operator. As you can see, there is the Person class and its instance created, so the operator returns true.

class Person {}
let person = new Person();
console.log(person instanceof Person); // logs true

Instanceof works fine for the function constructors as well.

function Person() {}
console.log (new Person() instanceof Person); // logs true

In the same way you can check if your object is an instance of the built-in classes such as Array, String, Map or Object. For example, in the next code sample there is an array of numbers and the instanceof operator shows that it belongs to the Array class. Keep in mind that it’s an instance of the Object class as well since Array is inherited from the Object. That’s why true is returned in both cases.

array = [0, 1, 2];
console.log(array instanceof Array); // logs true
console.log(array instanceof Object); // logs true

How it works

Usually during its execution the instanceof operator goes through the chain of prototypes. However, this behavior can be changed by means of the Symbol.hasInstance() static method. 

The algorithm of the instanceof operator is simple. It checks if the class contains the Symbol.hasInstance() method. If there is such a method, the operator will just return true or false and that’s all. Thus, the way to configure the work of the instanceof operator manually is by implementing the static Symbol.hasInstance() method. The code below illustrates such a case.

class Person {
    static [Symbol.hasInstance](object) {
        if (object.isAlive) return true;
    }
}

let object = {isAlive : true};
console.log(object instanceof Person); // logs true

From this example you can see how instanceof will return true for any object that has the isAlive property because such behavior is specified in the static Symbol.hasInstance method. 

Most of the classes do not have such a method implemented. In these cases the instanceof operator uses the standard logic and checks the prototype chain to see if any of the prototypes are equal to the Class.prototype. 

If any of the comparisons from the following code returns true, the result would be true as well, otherwise false would be returned. In this way you can see how this operator works with inheritance. 

Object.prototype === Class.prototype;
Object.prototype.prototype === Class.prototype;
Object.prototype.prototype.prototype === Class.prototype;

The difference between typeof and instanceof

Both typeof and instanceof operators are often used in order to check if the variable is empty or what its type is. However, they don’t work in the same way. For example, when you create a simple string and check its type, the returned result would be string. At the same time, if you check whether this variable is an instance of the String class, you get false.

string = "abcd";
console.log(typeof string); // logs "string"
console.log ( string instanceof String); // logs "false"

The typeof operator allows you to check if the value belongs to one of the six primitive data types: number, string, boolean, object, function or undefined, while instanceof works directly with the classes. 

It might be confusing but string=”abcd” is not the same as new String(“abcd”). In the first case you work with a primitive string, in the latter one there is an object created. So the result of typeof(new String(“abcd”)) would be an object. 

console.log(typeof (new String("abcd"))); // logs "object"
console.log ( (new String("abcd")) instanceof String); // logs "true"

Therefore, anytime you work with a primitive variable or want to check its root type - use the typeof operator, otherwise instanceof is a proper solution. One could say that the instanceof operator is better to use with everything created with the new keyword. However, there is one exception - a function. The operator will recognize functions created even by a regular declaration as shown in the example below.

function f() {}
console.log(typeof f); // logs "object"
console.log ( f instanceof Function); // logs "true" 

While comparing the two operators, productivity also matters. Typeofchecks the root type only once when instanceof needs to go through the whole chain of prototypes. Plus, the first operator can return the actual type of the variable while the latter one results in one of the two boolean values only: either true or false.   

Conclusion

The instanceof operator allows you to check whether the object belongs to a certain class or not. It returns true if the property of the prototype appears anywhere in the prototype chain or false otherwise. 

Beginners often mix up the instanceof and typeof operators. Even though they may seem to be similar, their concept is quite different. Typeof is used while working with the primitive variables or literals only and returns their data type. The typeofoperator is generally faster than the instanceof, so for situations when both of them can be used it’s much better to take the first one.