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. Typeof
checks 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 typeof
operator 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.