JavaScript 38 🧬 instanceof operator
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true
console.log(dog instanceof Array); // false
const arr = [1, 2, 3];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true
console.log([] instanceof Object); // true
console.log({} instanceof Object); // true
console.log("hello" instanceof String); // false (primitive)
console.log(new String("hello") instanceof String); // true (object)
The instanceof operator checks whether an object was created by a specific constructor — or more precisely, whether that constructor’s prototype appears anywhere in the object’s prototype chain. It’s the standard way to ask “is this a Date?”, “is this an Array?”, “is this a Dog?”.
Key point: instanceof walks the prototype chain. If the constructor’s prototype is anywhere up the chain, the result is true. This is why dog instanceof Animal works — Dog extends Animal, so Animal.prototype is in dog‘s chain.
a – What is instanceof and how it works
instanceof is a binary operator that takes an object on the left and a constructor (or class) on the right. It returns true or false.
Basic syntax:
object instanceof Constructor
Example:
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true
console.log(dog instanceof Array); // false
How it works — walking the prototype chain:
When you write dog instanceof Dog, JavaScript does this:
- Take
Dog.prototype - Start at
dog.__proto__ - Walk up the chain:
dog.__proto__,dog.__proto__.__proto__, … - If any link equals
Dog.prototype, returntrue - If you reach
null, returnfalse
┌──────────────────────────────────────────────┐
│ dog's prototype chain │
│ │
│ dog │
│ │ │
│ ▼ │
│ Dog.prototype ← instanceof Dog ✅ │
│ │ │
│ ▼ │
│ Animal.prototype ← instanceof Animal ✅ │
│ │ │
│ ▼ │
│ Object.prototype ← instanceof Object ✅ │
│ │ │
│ ▼ │
│ null │
│ │
└──────────────────────────────────────────────┘
This is why dog instanceof Animal is true — Animal.prototype is in the chain even though dog was created by Dog.
instanceof vs typeof:
| Aspect | typeof | instanceof |
|---|---|---|
| Operand | Any value | Object + constructor |
| Returns | String | Boolean |
| Primitives | Detects them | Always false |
| Custom classes | "object" — useless | Works correctly |
| Arrays | "object" — wrong | instanceof Array ✅ |
null | "object" — bug | null instanceof X → false |
console.log(typeof []); // "object" — not helpful
console.log([] instanceof Array); // true — useful
console.log(typeof null); // "object" — historical bug
console.log(null instanceof Object); // false — correct
console.log(typeof "hi"); // "string"
console.log("hi" instanceof String); // false — primitive
instanceof and primitives:
instanceof only works on objects. Primitives return false even when wrapped:
console.log("hello" instanceof String); // false
console.log(new String("hello") instanceof String); // true
console.log(42 instanceof Number); // false
console.log(true instanceof Boolean); // false
If you need to check a primitive’s type, use typeof.
instanceof with built-in types:
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new Date() instanceof Date); // true
console.log(/abc/ instanceof RegExp); // true
console.log(new Map() instanceof Map); // true
console.log(new Set() instanceof Set); // true
console.log((function(){}) instanceof Function); // true
instanceof with null and undefined:
console.log(null instanceof Object); // false
console.log(undefined instanceof Object); // false
Never throws — always returns false.
b – instanceof with classes and inheritance
instanceof shines when you have class hierarchies. It tells you whether an object belongs to a class or any of its ancestors.
Class hierarchy:
class Animal {
speak() { return 'sound'; }
}
class Dog extends Animal {
speak() { return 'woof'; }
}
class Cat extends Animal {
speak() { return 'meow'; }
}
const dog = new Dog();
const cat = new Cat();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Cat); // false
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
console.log(cat instanceof Dog); // false
The hierarchy:
Animal
/ \
Dog Cat
│ │
dog cat
dog is an instance of Dog, Animal, and Object. It’s not an instance of Cat or Array.
Multiple levels of inheritance:
class A {}
class B extends A {}
class C extends B {}
const c = new C();
console.log(c instanceof C); // true
console.log(c instanceof B); // true
console.log(c instanceof A); // true
console.log(c instanceof Object); // true
The chain walks all the way up.
instanceof for type guards:
function describe(animal) {
if (animal instanceof Dog) {
return 'A dog: ' + animal.speak();
}
if (animal instanceof Cat) {
return 'A cat: ' + animal.speak();
}
if (animal instanceof Animal) {
return 'Some animal: ' + animal.speak();
}
return 'Not an animal';
}
console.log(describe(new Dog())); // A dog: woof
console.log(describe(new Cat())); // A cat: meow
console.log(describe(new Animal())); // Some animal: sound
console.log(describe({})); // Not an animal
Order matters: Check the most specific class first. If you checked
AnimalbeforeDog, everyDogwould matchAnimaland you’d never reach theDogbranch.
instanceof with custom errors:
class ValidationError extends Error {}
class NetworkError extends Error {}
try {
throw new ValidationError('Invalid email');
} catch (err) {
if (err instanceof ValidationError) {
console.log('Validation problem:', err.message);
} else if (err instanceof NetworkError) {
console.log('Network problem:', err.message);
} else if (err instanceof Error) {
console.log('Other error:', err.message);
}
}
// [ Validation problem: Invalid email ]
This is the idiomatic way to handle custom error types.
instanceof with abstract-like base classes:
class Shape {
area() { throw new Error('Not implemented'); }
}
class Circle extends Shape {
constructor(r) { super(); this.r = r; }
area() { return Math.PI * this.r ** 2; }
}
class Square extends Shape {
constructor(s) { super(); this.s = s; }
area() { return this.s ** 2; }
}
function printArea(shape) {
if (!(shape instanceof Shape)) {
throw new TypeError('Expected a Shape');
}
console.log(shape.area().toFixed(2));
}
printArea(new Circle(5)); // 78.54
printArea(new Square(4)); // 16.00
try {
printArea({});
} catch (e) {
console.log(e.message);
}
// [ Expected a Shape ]
Subclass instance checks:
class Vehicle {}
class Car extends Vehicle {}
class ElectricCar extends Car {}
const tesla = new ElectricCar();
console.log(tesla instanceof ElectricCar); // true
console.log(tesla instanceof Car); // true
console.log(tesla instanceof Vehicle); // true
console.log(tesla instanceof Object); // true
Overriding Symbol.hasInstance:
You can customize instanceof for a class by defining Symbol.hasInstance:
class EvenNumber {
static [Symbol.hasInstance](value) {
return typeof value === 'number' && value % 2 === 0;
}
}
console.log(2 instanceof EvenNumber); // true
console.log(3 instanceof EvenNumber); // false
console.log(4 instanceof EvenNumber); // true
Now instanceof EvenNumber doesn’t walk the prototype chain — it runs your custom check. This is powerful but rare.
instanceof does not work across realms:
Objects created in a different realm (iframe, Worker, VM) have different Array, Object, etc. constructors, so instanceof fails:
// In a browser, an array from an iframe
iframeArray instanceof Array; // false — different Array constructor
Use Array.isArray() for cross-realm array checks.
c – instanceof vs alternatives
instanceof is one tool among several. Knowing when to use something else prevents bugs.
instanceof vs typeof:
typeof 42 // "number"
typeof "hi" // "string"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" ← famous bug
typeof [] // "object"
typeof {} // "object"
typeof function(){} // "function"
typeof is for primitives and "function". Use instanceof for custom classes and built-ins.
instanceof vs Array.isArray:
console.log([] instanceof Array); // true
console.log(Array.isArray([])); // true
Both work, but Array.isArray() is cross-realm safe — it works with arrays from iframes and Workers.
// In a browser
iframe.contentWindow.Array === Array; // false
iframeArray instanceof Array; // false ❌
Array.isArray(iframeArray); // true ✅
Use Array.isArray() when you might receive arrays from another realm.
instanceof vs constructor:
const arr = [];
console.log(arr.constructor === Array); // true
console.log(arr instanceof Array); // true
.constructor is fragile — it can be overwritten:
arr.constructor = Object;
console.log(arr.constructor === Array); // false ❌
console.log(arr instanceof Array); // true ✅
instanceof is more robust.
instanceof vs Object.prototype.toString.call:
const tag = Object.prototype.toString.call([]);
console.log(tag); // "[object Array]"
This is the oldest and most portable type check. It works across realms but is verbose. Modern code prefers instanceof for objects and typeof for primitives.
instanceof vs duck typing:
Duck typing asks “does it behave like X?” instead of “was it made by X?”
// instanceof
if (obj instanceof Array) { ... }
// duck typing
if (typeof obj.length === 'number' && typeof obj.push === 'function') { ... }
Duck typing is more flexible (works with array-likes) but less precise.
Comparison table:
| Check | Use for | Cross-realm |
|---|---|---|
typeof | Primitives, functions | ✅ |
instanceof | Custom classes, built-ins | ❌ |
Array.isArray | Arrays | ✅ |
.constructor | Quick check | ❌ (mutable) |
Object.prototype.toString | Portable type detection | ✅ |
| Duck typing | Interface-like checks | ✅ |
When to use instanceof:
- Checking custom class membership
- Checking error subclasses in
catch - Type guards in functions
- Anywhere the object was created in the same realm
When to use something else:
- Primitives →
typeof - Arrays across realms →
Array.isArray - Portable detection →
Object.prototype.toString - Behavior-based checks → duck typing
Complete Example Session
// ============================================
// PART 1: BASIC INSTANCEOF
// ============================================
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog);
// [ true ]
console.log(dog instanceof Animal);
// [ true ]
console.log(dog instanceof Object);
// [ true ]
console.log(dog instanceof Array);
// [ false ]
// ============================================
// PART 2: BUILT-IN TYPES
// ============================================
const arr = [1, 2, 3];
console.log(arr instanceof Array);
// [ true ]
console.log(arr instanceof Object);
// [ true ]
console.log([] instanceof Object);
// [ true ]
console.log({} instanceof Object);
// [ true ]
// ============================================
// PART 3: PRIMITIVES
// ============================================
console.log("hello" instanceof String);
// [ false ]
console.log(new String("hello") instanceof String);
// [ true ]
console.log(42 instanceof Number);
// [ false ]
// ============================================
// PART 4: NULL AND UNDEFINED
// ============================================
console.log(null instanceof Object);
// [ false ]
console.log(undefined instanceof Object);
// [ false ]
// ============================================
// PART 5: HIERARCHY
// ============================================
class A {}
class B extends A {}
class C extends B {}
const c = new C();
console.log(c instanceof C);
// [ true ]
console.log(c instanceof B);
// [ true ]
console.log(c instanceof A);
// [ true ]
console.log(c instanceof Object);
// [ true ]
// ============================================
// PART 6: SIBLINGS
// ============================================
class Dog2 extends Animal {}
class Cat2 extends Animal {}
const d = new Dog2();
const cat = new Cat2();
console.log(d instanceof Dog2);
// [ true ]
console.log(d instanceof Cat2);
// [ false ]
console.log(d instanceof Animal);
// [ true ]
// ============================================
// PART 7: TYPE GUARDS
// ============================================
function describe(animal) {
if (animal instanceof Dog2) return 'dog';
if (animal instanceof Cat2) return 'cat';
if (animal instanceof Animal) return 'animal';
return 'unknown';
}
console.log(describe(new Dog2()));
// [ dog ]
console.log(describe(new Cat2()));
// [ cat ]
console.log(describe(new Animal()));
// [ animal ]
console.log(describe({}));
// [ unknown ]
// ============================================
// PART 8: CUSTOM ERRORS
// ============================================
class ValidationError extends Error {}
class NetworkError extends Error {}
function throwError(type) {
if (type === 'v') throw new ValidationError('bad input');
if (type === 'n') throw new NetworkError('no connection');
}
try {
throwError('v');
} catch (err) {
if (err instanceof ValidationError) {
console.log('Validation:', err.message);
}
}
// [ Validation: bad input ]
// ============================================
// PART 9: VS TYPEOF
// ============================================
console.log(typeof []);
// [ object ]
console.log([] instanceof Array);
// [ true ]
console.log(typeof null);
// [ object ]
console.log(null instanceof Object);
// [ false ]
// ============================================
// PART 10: ARRAY.ISARRAY
// ============================================
console.log([] instanceof Array);
// [ true ]
console.log(Array.isArray([]));
// [ true ]
// ============================================
// PART 11: CONSTRUCTOR PROPERTY
// ============================================
const a = [];
console.log(a.constructor === Array);
// [ true ]
a.constructor = Object;
console.log(a.constructor === Array);
// [ false ] ← fragile
console.log(a instanceof Array);
// [ true ] ← robust
// ============================================
// PART 12: SYMBOL.HASINSTANCE
// ============================================
class EvenNumber {
static [Symbol.hasInstance](value) {
return typeof value === 'number' && value % 2 === 0;
}
}
console.log(2 instanceof EvenNumber);
// [ true ]
console.log(3 instanceof EvenNumber);
// [ false ]
// ============================================
// PART 13: DATE / REGEXP / MAP
// ============================================
console.log(new Date() instanceof Date);
// [ true ]
console.log(/abc/ instanceof RegExp);
// [ true ]
console.log(new Map() instanceof Map);
// [ true ]
console.log(new Set() instanceof Set);
// [ true ]
// ============================================
// PART 14: FUNCTIONS
// ============================================
console.log(function(){} instanceof Function);
// [ true ]
console.log(() => {} instanceof Function);
// [ true ]
// ============================================
// PART 15: CHAIN CHECK
// ============================================
class Base {}
class Mid extends Base {}
class Leaf extends Mid {}
const leaf = new Leaf();
console.log(leaf instanceof Leaf);
// [ true ]
console.log(leaf instanceof Mid);
// [ true ]
console.log(leaf instanceof Base);
// [ true ]
console.log(leaf instanceof Object);
// [ true ]
// ============================================
// PART 16: SHAPE EXAMPLE
// ============================================
class Shape {}
class Circle extends Shape {
constructor(r) { super(); this.r = r; }
}
class Square extends Shape {
constructor(s) { super(); this.s = s; }
}
function checkShape(s) {
if (s instanceof Circle) return 'circle';
if (s instanceof Square) return 'square';
if (s instanceof Shape) return 'shape';
return 'not a shape';
}
console.log(checkShape(new Circle(5)));
// [ circle ]
console.log(checkShape(new Square(4)));
// [ square ]
console.log(checkShape(new Shape()));
// [ shape ]
console.log(checkShape({}));
// [ not a shape ]
// ============================================
// PART 17: NESTED HIERARCHY
// ============================================
class Vehicle {}
class Car extends Vehicle {}
class ElectricCar extends Car {}
const tesla = new ElectricCar();
console.log(tesla instanceof ElectricCar);
// [ true ]
console.log(tesla instanceof Car);
// [ true ]
console.log(tesla instanceof Vehicle);
// [ true ]
console.log(tesla instanceof Object);
// [ true ]
// ============================================
// PART 18: MIXINS
// ============================================
const Serializable = {
serialize() { return JSON.stringify(this); }
};
class User {}
Object.assign(User.prototype, Serializable);
const u = new User();
console.log(u instanceof User);
// [ true ]
console.log(typeof u.serialize);
// [ function ]
// ============================================
// PART 19: POLYMORPHISM
// ============================================
class Pay {
process() { return 'generic'; }
}
class CardPay extends Pay {
process() { return 'card'; }
}
class CashPay extends Pay {
process() { return 'cash'; }
}
function pay(p) {
if (!(p instanceof Pay)) {
throw new TypeError('Expected a Pay');
}
return p.process();
}
console.log(pay(new CardPay()));
// [ card ]
console.log(pay(new CashPay()));
// [ cash ]
// ============================================
// PART 20: FULL SCRIPT
// ============================================
class Animal2 {}
class Dog3 extends Animal2 {}
const dog3 = new Dog3();
console.log(dog3 instanceof Dog3);
console.log(dog3 instanceof Animal2);
console.log(dog3 instanceof Object);
console.log(dog3 instanceof Array);
const arr2 = [1, 2, 3];
console.log(arr2 instanceof Array);
console.log(arr2 instanceof Object);
console.log([] instanceof Object);
console.log({} instanceof Object);
console.log("hello" instanceof String);
console.log(new String("hello") instanceof String);
Quick Reference
instanceof Basics
| Expression | Result |
|---|---|
obj instanceof Constructor | true or false |
null instanceof X | false |
undefined instanceof X | false |
primitive instanceof X | false |
obj instanceof Object | true (unless Object.create(null)) |
typeof vs instanceof
| Check | typeof | instanceof |
|---|---|---|
| Primitives | ✅ | ❌ |
| Functions | "function" | Function |
| Arrays | "object" ❌ | Array ✅ |
| null | "object" ❌ | false |
| Custom classes | "object" ❌ | ✅ |
Built-in Checks
| Value | instanceof |
|---|---|
[] | Array, Object |
{} | Object |
new Date() | Date, Object |
/re/ | RegExp, Object |
function(){} | Function, Object |
new Map() | Map, Object |
new Set() | Set, Object |
Promise.resolve() | Promise, Object |
Hierarchy
| Object | instanceof |
|---|---|
new ElectricCar() | ElectricCar, Car, Vehicle, Object |
new Dog() | Dog, Animal, Object |
new ValidationError() | ValidationError, Error, Object |
Alternatives
| Check | Use for | Cross-realm |
|---|---|---|
typeof | Primitives | ✅ |
instanceof | Classes | ❌ |
Array.isArray | Arrays | ✅ |
Object.prototype.toString.call | Everything | ✅ |
.constructor | Quick check | ❌ mutable |
Best Practices
✅ Do This:
// Check most specific first
if (x instanceof Dog) { ... }
else if (x instanceof Animal) { ... } // ✅
// Use instanceof for error types
if (err instanceof ValidationError) { ... } // ✅
// Use Array.isArray for arrays
Array.isArray(value) // ✅
// Use typeof for primitives
typeof value === 'string' // ✅
// Validate class membership
if (!(x instanceof Shape)) {
throw new TypeError('Expected Shape');
} // ✅
// Use instanceof in type guards
function isDog(x) {
return x instanceof Dog;
} // ✅
// Check instanceof Object for "is an object"
value !== null && typeof value === 'object' // ✅ preferred
❌ Don’t Do This:
// Don't use instanceof for primitives
"hi" instanceof String // ❌ false
// Don't rely on instanceof across realms
iframeArray instanceof Array // ❌ false
Array.isArray(iframeArray) // ✅
// Don't use .constructor as a type check
x.constructor === Array // ❌ can be reassigned
// Don't check parent before child
if (x instanceof Animal) { ... }
else if (x instanceof Dog) { ... } // ❌ Dog never reached
// Don't use instanceof with null
null instanceof Object // ✅ false, but be careful
// Don't confuse instanceof with typeof
typeof [] === 'array' // ❌ no such thing
// Don't forget Object.create(null)
const o = Object.create(null);
o instanceof Object // ❌ false
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Primitives | Always false | Use typeof |
| Cross-realm | false for real arrays | Use Array.isArray |
| Parent before child | Child branch unreachable | Check specific first |
null instanceof X | Returns false (never throws) | Handle null separately |
Object.create(null) | Not an Object instance | Check directly |
.constructor mutable | Can be overwritten | Use instanceof |
| Different realm | Different constructors | Use Object.prototype.toString |
Confusing with typeof | Both “check type” | Use typeof for primitives |
Real-World Examples
1. Basic Class Check
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog);
// [ true ]
console.log(dog instanceof Animal);
// [ true ]
console.log(dog instanceof Object);
// [ true ]
console.log(dog instanceof Array);
// [ false ]
2. Built-in Types
const arr = [1, 2, 3];
console.log(arr instanceof Array);
// [ true ]
console.log(arr instanceof Object);
// [ true ]
console.log([] instanceof Object);
// [ true ]
console.log({} instanceof Object);
// [ true ]
3. Primitive vs Object
console.log("hello" instanceof String);
// [ false ]
console.log(new String("hello") instanceof String);
// [ true ]
4. Error Type Handling
class ValidationError extends Error {}
try {
throw new ValidationError('Invalid input');
} catch (err) {
if (err instanceof ValidationError) {
console.log('Validation failed:', err.message);
}
}
// [ Validation failed: Invalid input ]
5. Type Guard
function isDate(x) {
return x instanceof Date;
}
console.log(isDate(new Date()));
// [ true ]
console.log(isDate('2024-01-01'));
// [ false ]
6. Multiple Constructors
const values = [
new Map(),
new Set(),
[],
{},
new Date(),
/regex/
];
for (const v of values) {
if (v instanceof Map) console.log('Map');
else if (v instanceof Set) console.log('Set');
else if (v instanceof Array) console.log('Array');
else if (v instanceof Date) console.log('Date');
else if (v instanceof RegExp) console.log('RegExp');
else console.log('Object');
}
// [ Map ]
// [ Set ]
// [ Array ]
// [ Object ]
// [ Date ]
// [ RegExp ]
7. Class Hierarchy Traversal
class A {}
class B extends A {}
class C extends B {}
const c = new C();
console.log(c instanceof C);
// [ true ]
console.log(c instanceof B);
// [ true ]
console.log(c instanceof A);
// [ true ]
console.log(c instanceof Object);
// [ true ]
8. Shape Area
class Shape {}
class Circle extends Shape {
constructor(r) { super(); this.r = r; }
area() { return Math.PI * this.r ** 2; }
}
class Square extends Shape {
constructor(s) { super(); this.s = s; }
area() { return this.s ** 2; }
}
function printArea(shape) {
if (!(shape instanceof Shape)) {
throw new TypeError('Expected a Shape');
}
console.log(shape.area().toFixed(2));
}
printArea(new Circle(5));
// [ 78.54 ]
printArea(new Square(4));
// [ 16.00 ]
9. instanceof vs typeof
console.log(typeof []);
// [ object ]
console.log([] instanceof Array);
// [ true ]
console.log(typeof null);
// [ object ]
console.log(null instanceof Object);
// [ false ]
10. Custom Symbol.hasInstance
class EvenNumber {
static [Symbol.hasInstance](v) {
return typeof v === 'number' && v % 2 === 0;
}
}
console.log(2 instanceof EvenNumber);
// [ true ]
console.log(3 instanceof EvenNumber);
// [ false ]
11. User Input Validation
function isArray(value) {
return value instanceof Array;
}
console.log(isArray([1, 2, 3]));
// [ true ]
console.log(isArray('hello'));
// [ false ]
12. Nested Inheritance Check
class Vehicle {}
class Car extends Vehicle {}
class ElectricCar extends Car {}
const tesla = new ElectricCar();
console.log(tesla instanceof ElectricCar);
// [ true ]
console.log(tesla instanceof Car);
// [ true ]
console.log(tesla instanceof Vehicle);
// [ true ]
13. Detect Custom Error
class AuthError extends Error {}
class NotFoundError extends Error {}
function handle(err) {
if (err instanceof AuthError) return 'auth';
if (err instanceof NotFoundError) return 'not found';
if (err instanceof Error) return 'generic';
return 'unknown';
}
console.log(handle(new AuthError()));
// [ auth ]
console.log(handle(new NotFoundError()));
// [ not found ]
console.log(handle(new Error()));
// [ generic ]
14. instanceof with Array.isArray
const data = [[1, 2], 'text', { a: 1 }, [3, 4]];
for (const item of data) {
if (Array.isArray(item)) {
console.log('Array with length', item.length);
} else {
console.log('Not an array');
}
}
// [ Array with length 2 ]
// [ Not an array ]
// [ Not an array ]
// [ Array with length 2 ]
15. instanceof in a Validation Function
function assertDate(value) {
if (!(value instanceof Date)) {
throw new TypeError('Expected Date');
}
return value.toISOString();
}
console.log(assertDate(new Date('2024-01-15')));
// [ 2024-01-15T00:00:00.000Z ]
try {
assertDate('2024-01-15');
} catch (e) {
console.log(e.message);
}
// [ Expected Date ]
16. Polymorphic Dispatch
class Notification {}
class Email extends Notification {
send() { return 'sending email'; }
}
class SMS extends Notification {
send() { return 'sending SMS'; }
}
function sendAll(list) {
for (const n of list) {
if (n instanceof Notification) {
console.log(n.send());
}
}
}
sendAll([new Email(), new SMS()]);
// [ sending email ]
// [ sending SMS ]
17. instanceof vs Duck Typing
const arrayLike = { length: 2, 0: 'a', 1: 'b' };
console.log(arrayLike instanceof Array);
// [ false ]
console.log(typeof arrayLike.length === 'number');
// [ true ]
18. Custom Collection
class Stack {
constructor() { this.items = []; }
push(x) { this.items.push(x); }
pop() { return this.items.pop(); }
}
class Queue extends Stack {
pop() { return this.items.shift(); }
}
const q = new Queue();
q.push(1);
q.push(2);
console.log(q instanceof Queue);
// [ true ]
console.log(q instanceof Stack);
// [ true ]
console.log(q.pop());
// [ 1 ]
19. instanceof in a Factory
class Logger {
log(msg) { console.log(msg); }
}
class FileLogger extends Logger {
log(msg) { /* write to file */ }
}
function createLogger(type) {
const logger = type === 'file' ? new FileLogger() : new Logger();
if (logger instanceof Logger) {
return logger;
}
throw new Error('Invalid logger');
}
const l = createLogger('file');
console.log(l instanceof FileLogger);
// [ true ]
20. Full Script
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog);
console.log(dog instanceof Animal);
console.log(dog instanceof Object);
console.log(dog instanceof Array);
const arr = [1, 2, 3];
console.log(arr instanceof Array);
console.log(arr instanceof Object);
console.log([] instanceof Object);
console.log({} instanceof Object);
console.log("hello" instanceof String);
console.log(new String("hello") instanceof String);
Visual: instanceof Walks the Chain
┌──────────────────────────────────────────────┐
│ instanceof Dog │
│ │
│ Start at: dog │
│ │
│ dog.__proto__ ───► Dog.prototype ✅ │
│ │
│ Result: true │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ instanceof Animal │
│ │
│ Start at: dog │
│ │
│ dog.__proto__ ───► Dog.prototype ✗ │
│ │ │
│ ▼ │
│ Dog.prototype.__proto__ ─► Animal.prototype ✅│
│ │
│ Result: true │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ instanceof Array │
│ │
│ Start at: dog │
│ │
│ dog.__proto__ ──► Dog.prototype ✗ │
│ Dog.prototype.__proto__ ─► Animal.prototype ✗│
│ Animal.prototype.__proto__ ─► Object.prototype ✗│
│ Object.prototype.__proto__ ─► null │
│ │
│ Result: false │
│ │
└──────────────────────────────────────────────┘
Visual: typeof vs instanceof
┌──────────────────────────────────────────────┐
│ Value typeof instanceof │
│ ────────────────────────────────────────── │
│ 42 "number" N/A │
│ "hi" "string" N/A │
│ true "boolean" N/A │
│ null "object" ❌ false │
│ undefined "undefined" false │
│ [] "object" ❌ Array ✅ │
│ {} "object" Object ✅ │
│ function(){} "function" Function ✅ │
│ new Date() "object" Date ✅ │
│ /regex/ "object" RegExp ✅ │
│ │
└──────────────────────────────────────────────┘
Summary
| Concept | Syntax | Example |
|---|---|---|
| Basic check | obj instanceof C | dog instanceof Dog |
| Inherited | dog instanceof Animal | true if extends |
| Object | x instanceof Object | Most objects true |
| Array | x instanceof Array | Also use Array.isArray |
| null | null instanceof X | Always false |
| Primitive | "hi" instanceof String | false |
| Error check | err instanceof Error | In catch blocks |
| Custom | x instanceof MyClass | Any class |
| Customize | Symbol.hasInstance | Override behavior |
Key takeaways:
instanceofchecks whether an object’s prototype chain includes the constructor’s prototype- It walks the entire chain — so a subclass instance matches all ancestor classes
- It returns
falsefor primitives — usetypeoffor those - It returns
falsefornullandundefined— never throws - Order matters in
if/else— check the most specific class first Array.isArray()is preferred for arrays because it works across realms.constructoris mutable —instanceofis more robust- Use
instanceofwith custom error classes for precisecatchhandling Symbol.hasInstancelets you customizeinstanceofbehaviorinstanceofdoesn’t cross realms (iframes, Workers) — useObject.prototype.toStringorArray.isArraytheretypeof nullis"object"(a historical bug) butnull instanceof Objectisfalse—instanceofis more correct here
Remember: instanceof answers “was this created by this class (or a subclass)?” It’s the right tool for class hierarchies, custom errors, and type guards. Use typeof for primitives, Array.isArray for arrays across realms, and instanceof for everything else. Watch out for the order of checks in if/else chains — specific first, general last. Master instanceof, and your type checks become reliable and expressive.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!