Introduction

If you’ve spent any time debugging JavaScript, you’ve probably run into type errors. You know the ones, where you try to call a method on something that turns out to be undefined or try to loop through something that isn’t actually an array. Been there, done that!

JavaScript gives us two main ways to check what we’re dealing with: typeof and instanceof. They might look like they do the same thing, but trust me, mixing them up can lead to some head-scratching bugs. Let’s break down how these two operators work and when you should reach for each one.

The typeof Operator

The typeof operator is probably the first type-checking tool most of us learn. It’s quick and easy, just stick it in front of any value and it tells you what kind of thing you’re working with. It’s especially handy for checking primitive types like numbers and strings.

Syntax

typeof operand;
// or
typeof operand; // With parentheses works too

What typeof Returns

typeof returns one of these string values:

Return ValueFor
"undefined"undefined values
"boolean"boolean values (true/false)
"number"numbers (including NaN)
"string"strings
"bigint"BigInt values
"symbol"Symbol values
"function"Functions
"object"Objects, arrays, null

Examples

// Primitive types
console.log(typeof 42); // "number"
console.log(typeof 'hello'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof 10n); // "bigint"
console.log(typeof Symbol()); // "symbol"

// Reference types
console.log(typeof {}); // "object"
console.log(typeof []); // "object" (arrays are objects)
console.log(typeof null); // "object" (this is a historical bug)
console.log(typeof function () {}); // "function"

Limitations of typeof

The typeof operator is useful, but it has some quirks that can trip you up:

  1. It calls arrays “objects”, which is technically true, but not very helpful when you need to know if something’s specifically an array
  2. It says null is an “object”, this is actually a famous bug in JavaScript that’s been around forever and can’t be fixed without breaking the web
  3. It can’t tell you what kind of object you’re dealing with, a Date, a RegExp, or your own custom object all just show up as “object”

The instanceof Operator

This is where instanceof comes into play. While typeof tells you the general category, instanceof answers a more specific question: “Was this object created from this particular constructor or class?”

It’s like the difference between asking “Is this a vehicle?” versus “Is this specifically a Toyota?”

Syntax

object instanceof constructor;

How instanceof Works

When you use instanceof, JavaScript looks through the object’s family tree (aka its prototype chain) to see if it descended from the constructor you’re checking. It will:

  • Return true if the object is related to that constructor
  • Return false if they’re not related

Examples

// Define a class
class Animal {
  constructor(name) {
    this.name = name;
  }
}

// Create some objects
const dog = new Animal('Rex');
const arr = [1, 2, 3];
const obj = { key: 'value' };

// Check instanceof
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true (Animal inherits from Object)
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true (arrays are objects)
console.log(obj instanceof Object); // true
console.log(obj instanceof Array); // false

Comparing typeof and instanceof

Here’s a practical comparison of when to use each operator:

class Person {
  constructor(name) {
    this.name = name;
  }
}

const john = new Person('John');
const numbers = [1, 2, 3];
const greeting = 'Hello';

// Using typeof
console.log(typeof john); // "object" (not very specific)
console.log(typeof numbers); // "object" (doesn't tell us it's an array)
console.log(typeof greeting); // "string" (correctly identifies primitive)

// Using instanceof
console.log(john instanceof Person); // true (correctly identifies the class)
console.log(numbers instanceof Array); // true (correctly identifies array)
console.log(greeting instanceof String); // false (primitives aren't instances)

// Primitives vs their object wrappers
console.log(typeof 'hello'); // "string"
console.log('hello' instanceof String); // false
console.log(new String('hello') instanceof String); // true

When to Use Each Operator

So when should you reach for which operator? Here’s my rule of thumb:

Use typeof when:

  1. You’re dealing with basic types like strings, numbers, and booleans
  2. You need to check if something exists (typeof myVar !== 'undefined')
  3. You need to know if something is a function before calling it
  4. You just need a quick check and don’t care about specific object types

Use instanceof when:

  1. You need to verify if something is an array (like before running a .map() on it)
  2. You’re working with your own classes or inheritance
  3. You need to tell different object types apart (like Date vs RegExp)
  4. You’re doing any serious object-oriented programming in JavaScript

Edge Cases and Gotchas

JavaScript wouldn’t be JavaScript without a few quirks to watch out for:

The null Problem

console.log(typeof null); // "object" (oops, that's not right!)

// Here's how I check for null instead
console.log(value === null); // true or false

This is probably JavaScript’s most famous quirk. typeof null gives "object", which makes no sense! This bug has been around since the dawn of JavaScript, and we’re stuck with it forever.

Primitives vs Object Wrappers

const str = 'hello'; // A primitive string
const strObj = new String('hello'); // A String object

console.log(typeof str); // "string"
console.log(typeof strObj); // "object"

console.log(str instanceof String); // false
console.log(strObj instanceof String); // true

This one catches people all the time. A normal string and a String object look similar but behave differently with our type checks!

Cross-frame Objects

Here’s a tricky one: if you pass objects between frames or windows (like a parent window and an iframe), instanceof can give you incorrect results. That’s because each window has its own set of constructors, and instanceof checks against the constructor, not just the shape of the object.

Conclusion

So which should you use, typeof or instanceof? Well, it really depends on what you’re trying to figure out:

  • Reach for typeof when you’re working with primitive values or just need a quick check
  • Go with instanceof when you need to know about object types and inheritance

In my own code, I typically use typeof for basic checks and sanity testing, and pull out instanceof when I’m working with class hierarchies or need to be specific about what kind of object I have.

The truth is, for really solid type checking in JavaScript, you’ll probably end up using a combination of both, plus some additional checks like Array.isArray() for those special cases.