When a catch block receives an error, it does not yet know what kind of error it is. A network problem and an invalid piece of data call for different reactions, and the code has to tell them apart before deciding anything.
instanceof is made for exactly that: identifying what an object is when typeof only ever answers 'object'.
Definition
instanceof returns true when the object on its left was built from the class or function on its right, directly or through inheritance.
class Animal {}
class Dog extends Animal {}
const rex = new Dog();
rex instanceof Dog; // true
rex instanceof Animal; // true
rex instanceof Object; // true
rex instanceof Array; // falseAn object is recognized as an instance of its own class, and also of every class it inherits from through extends. That is what lets you write a broad test or a narrow one depending on what you need.
The most frequent use
Sorting errors inside a try block is the common case, because every error shares the same type without sharing the same meaning.
try {
await save(form);
} catch (error) {
if (error instanceof TypeError) {
console.error('Bug in the code:', error.message);
} else {
console.error('Saving failed');
}
}The same logic applies to classes you write yourself: a business error created with class and extends from Error is then recognized in a single line.
The three cases where it gets it wrong
- Primitive values are not objects.
'abc' instanceof Stringisfalse, even though the text really is a string. For those values, typeof is the right tool. - Boundaries between contexts. An array coming from an embedded frame, or from a context created with Node's
vmmodule, was not built from the same Array: the test fails although the value truly is an array.Array.isArray()does not suffer from this. - A plain object tells you nothing. Everything coming out of JSON is an instance of
Object, which informs you about nothing at all. Data received over the network is checked by its content, not by its class.
The value on the right must be a class or a function. value instanceof 'Dog' raises an error, because a string cannot act as a constructor: write the class name itself, without quotes.
Frequently asked questions
Does it work with old constructor functions?
Yes, and that was its original purpose. A function called with new produces an object that instanceof recognizes, exactly like a class. On this particular point, classes are only a more readable way of writing the same mechanism.
Why not compare constructor.name instead?
Because that name is a string, which says nothing about inheritance and often disappears when the code sent to the browser is minified. instanceof follows the object's real lineage and does not depend on names surviving into the final file.
instanceof or typeof, which one do I use?
They answer different questions. typeof handles primitive values, text, number, boolean, while instanceof handles objects built from a class. In a function accepting varied input, both are often used in sequence, starting with the broader test.