ReviseAlgo Logo

OOP in JavaScript

The instanceof Operator & Symbol.hasInstance

Master runtime type checking in JavaScript. Learn the instanceof operator, prototype chains, and custom type validation using Symbol.hasInstance.

Last Updated: July 15, 2026 10 min read

1. Introduction

The instanceof operator checks if an object's prototype chain contains the prototype property of a constructor function. ES6 introduced the Symbol.hasInstance well-known symbol, allowing you to customize the behavior of the instanceof operator.

2. Why It Matters

The standard instanceof check is based strictly on prototype inheritance. If you want to check if an object implements a specific interface structure or validate data dynamically (such as checking if a value is an integer), Symbol.hasInstance allows you to customize the operator's behavior.

3. Real-World Analogy

Think of a Passport Control checkpoint:

  • Standard instanceof (Family Lineage Check): An officer checks your lineage: "Does your father have matching heritage? Yes. Does your grandfather? Yes." If the lineage matches, you are approved. This is prototype chain matching.
  • Symbol.hasInstance (Custom Entry Visa): A custom entry visa program. Instead of checking family lineage, the country defines a custom validation rule (like having a specific work visa). Anyone who meets this rule is approved, regardless of family lineage.

4. The instanceof Operator

By default, instanceof traverses the prototype chain of the left-hand object, comparing it with the prototype property of the right-hand constructor:

5. Customizing instanceof (Symbol.hasInstance)

You can customize the behavior of the instanceof operator by implementing the static [Symbol.hasInstance] method on a class:

6. Practical Example

This script demonstrates implementing a structural interface validation check using Symbol.hasInstance:

7. Common Mistakes

  • Assuming instanceof checks primitive values: The standard instanceof operator only works on objects. Calling "hello" instanceof String returns false because primitives do not have prototype chains. Use typeof for primitive values.

8. Quick Quiz

Q1: Which static method must you define on a class constructor to customize the behavior of the instanceof operator?

A) static [Symbol.hasInstance](instance)

B) static validateInstance(instance)

Answer: A — The static method static [Symbol.hasInstance](instance) is called when executing the instanceof operator, allowing you to define custom validation rules.

9. Scenario-Based Challenge

The JSON API Response Validator:

An application processes API responses. You want to check if a response contains the required database properties: { id: 1, data: {} }. Implement a class validator using Symbol.hasInstance that validates the object structure.

10. Debugging Exercise

Explain why this primitive check returns false, and how to resolve it:

const myAge = 25;

// Objective: verify if age is a Number object console.log(myAge instanceof Number); // logs false! Why?

View Solution

Diagnosis: The value myAge is a primitive number, not a Number object instance. The instanceof operator only works on objects, returning false for primitives.

Fix: Use the typeof operator to validate primitive values, or create a Number object wrapper if you must use instanceof:

console.log(typeof myAge === 'number'); // true (Checks primitive type)
console.log(new Number(25) instanceof Number); // true (Checks object instance)

11. Interview Questions

🟢 Q1: Explain how the instanceof operator works and how Symbol.hasInstance can customize its behavior.

Answer:
How it works: The instanceof operator checks if the prototype property of the right-hand constructor function appears anywhere in the prototype chain of the left-hand object. It recursively traverses the prototype chain: obj.__proto__.__proto__ ... === Constructor.prototype.
Symbol.hasInstance: ES6 allows you to override this default behavior by implementing the static [Symbol.hasInstance] method on the class constructor. When the operator runs, it calls this method with the instance as an argument, allowing you to implement custom validation rules (like checking structural interfaces or types).

12. Production Considerations

  • Avoid Complex Logic: The instanceof operator is called frequently during type checking. Avoid writing heavy calculations or network calls inside [Symbol.hasInstance] to prevent performance bottlenecks.