In JavaScript, the instanceof operator is used to check whether an object’s prototype chain contains the .prototype property of a specific constructor. In simpler terms, it tells you if an object is an “instance” of a particular class or constructor function.

1. Syntax and Basic Usage

The operator takes an object on the left and a constructor (class or function) on the right. It returns a boolean: true or false.

JavaScript

object instanceof constructor

Basic Example:

JavaScript

class Animal {}
class Dog extends Animal {}

const myDog = new Dog();

console.log(myDog instanceof Dog);    // true
console.log(myDog instanceof Animal); // true (because of inheritance)
console.log(myDog instanceof Object); // true (everything is an object)
console.log(myDog instanceof Array);  // false

2. Basic Usage and Built-in Types

instanceof is most commonly used to distinguish between different types of built-in objects that would otherwise all return "object" when using the typeof operator.

JavaScript

const colors = ['red', 'green', 'blue'];
const pattern = /abc/g;

console.log(colors instanceof Array);  // true
console.log(colors instanceof Object); // true (Array inherits from Object)
console.log(pattern instanceof RegExp); // true
console.log(pattern instanceof Array);  // false

The typeof Limitation

While typeof is excellent for primitive types (strings, numbers, booleans), it is notoriously blunt with objects:

  • typeof [] returns “object”
  • typeof {} returns “object”
  • typeof /regex/ returns “object” instanceof provides the necessary granularity to identify these specific structures.

3. How it Works (The Prototype Chain)

The instanceof operator doesn’t actually check the “class” of an object. Instead, it looks at the object’s prototype chain. It asks: “Is Dog.prototype anywhere in the chain of objects linked to myDog?”

If you manually change an object’s prototype, instanceof will reflect that change immediately.

JavaScript

function Car() {}
const shape = {};

console.log(shape instanceof Car); // false

// Manually changing the prototype
Object.setPrototypeOf(shape, Car.prototype);
console.log(shape instanceof Car); // true

5. Critical Gotchas and Limitations

A. The “Multiple Realms” Problem

The biggest weakness of instanceof occurs when working with multiple execution contexts, such as iframes or worker threads. Each realm has its own global objects. An array created in an iframe will have the Array.prototype of that iframe.

JavaScript

// In a browser with an iframe
const iframeArray = window.frames[0].someArray;
console.log(iframeArray instanceof Array); // false (different Array constructors!)

Solution: Use Array.isArray(value) for arrays, as it is robust across realms.

B. Primitives vs. Objects

instanceof does not work with literal primitives because primitives are not objects and do not have prototype chains until they are wrapped.

JavaScript

const str = "hello";
const strObj = new String("hello");

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

5. instanceof in Inheritance

When using classes, instanceof respects the inheritance hierarchy. If a class extends another, an instance of the child is also considered an instance of the parent.

JavaScript

class Parent {}
class Child extends Parent {}

const kid = new Child();

// Polymorphism check
function greet(person) {
  if (person instanceof Parent) {
    console.log("Hello, family member!");
  }
}

greet(kid); // "Hello, family member!"

6. Advanced Pattern: Polymorphic Functionality

Developers use instanceof to create functions that can handle different inputs gracefully (overloading).

JavaScript
function processData(input) {
  if (input instanceof HTMLFormElement) {
    return new FormData(input);
  } else if (input instanceof Map) {
    return Object.fromEntries(input);
  } else if (typeof input === 'string') {
    return JSON.parse(input);
  }
}

By checking the instance, the function can adapt its logic to the specific structure of the object provided, making the API more flexible.

Would you like to explore how to use Object.prototype.toString.call() as a more robust alternative for type checking that works across different browser realms?

Categorized in:

Javascript,