Explain Codes LogoExplain Codes Logo

What's the difference between typeof and instanceof in JavaScript and when should they each be used?

javascript
type-checking
instanceof
typeof-operator
Nikita BarsukovbyNikita Barsukov·Aug 28, 2024
TLDR

typeof identifies a variable's primitive data type, such as 'number' or 'string'. instanceof, on the other hand, checks the inheritance, confirming whether an object is derived from a particular prototype/class.

typeof 'hello' === 'string'; // true new Date() instanceof Date; // true

Indicating the basic types with typeof

Detecting the built-in types

We mainly apply the typeof operator to identify primitive data types such as 'number', 'string', 'boolean', 'undefined', 'object', 'symbol' (from ECMAScript 2015), and 'function'.

Peculiarly typeof is also robust when assessing if variables are defined or if they exist, thus preventing errors that might be caused by accessing undeclared variables:

if (typeof myVar !== 'undefined') { // myVar is safe and sound }

Understanding the quirks of typeof

While very useful, typeof does have its quirks, which must be understood to avoid surprises:

  • typeof null returns 'object' - a known quirk in JavaScript.
  • Arrays are technically objects, so typeof [] also returns 'object'.
  • typeof NaN returns 'number', despite NaN standing for "Not-A-Number".

So when dealing with functions, typeof is a pretty trusty sidekick:

if (typeof callBack === 'function') { // let's call this function back! 📞 }

Confirming inheritance with instanceof

Scrutinizing custom types and prototypes

The instanceof operator comes into play when determining if an object is an instance of a specific prototype or class. This can be particularly useful when dealing with complex built-in types like Function and custom-provided types:

function MyCustomType(name) { this.name = name; } const myVar = new MyCustomType('MyVar'); console.log(myVar instanceof MyCustomType); // true

instanceof digs into the prototype chain, checking for inherited properties all the way up the ladder 🪜.

Insights for wise use of instanceof

An important consideration for instanceof is that checks may fail across separate execution contexts (e.g., iframes in browsers, multiple VM contexts in Node.js) because the compared objects come from different origin scopes.

For primitives and their corresponding object wrappers (like new String('hello')), instanceof can be particularly helpful to bridge inconsistencies across various browsers:

console.log('hello' instanceof String); // false console.log(new String('hello') instanceof String); // true - got'cha!

Moreover, instanceof can also tell you if a variable is null:

let nonExistent = null; console.log(nonExistent instanceof Object); // false - sorry, not an object 🤷‍♂️

Complementary usage and performance boosters

Combining them for stronger, cross-browser consistent checks

You can leverage both typeof and instanceof for more robust, cross-browser consistent type checking:

function isString(value) { return typeof value === 'string' || value instanceof String; }

Modifying prototypes with caution

Altering an object's prototype could affect instanceof checks and could potentially dampen performance. Steer clear of modifying standard prototypes for maximum compatibility.

Optimizing performance with instanceof

Interestingly, instanceof might be faster in some situations because it compares memory pointers in the prototype chain rather than evaluating the type of the value itself.