All topics
Fundamentalsbeginner

typeof and instanceof Operators

Two different tools for checking a value's type at runtime — one for primitives, one for constructor-based checks on objects.

Two ways to check a type at runtime, and neither covers everything.

`typeof` is like glancing at a package's shipping label to see if it says 'liquid,' 'solid,' or 'fragile' — a coarse category. `instanceof` is like checking a product's manufacturer stamp to confirm it specifically came from a particular factory (constructor) somewhere down its supply chain (prototype chain).

Key Concepts

1
typeof returns a string, and it has two famous gaps.
    typeof 42            // 'number'
    typeof 'a'           // 'string'
    typeof true          // 'boolean'
    typeof undefined     // 'undefined'
    typeof Symbol()      // 'symbol'
    typeof 10n           // 'bigint'
    typeof function(){}  // 'function'
    typeof {}            // 'object'
    typeof []            // 'object'   <- not 'array'
    typeof null          // 'object'   <- a bug from 1995, kept for
                         //               compatibility
typeof
2
So typeof distinguishes primitives and functions, and tells you almost nothing about objects.
typeof
3
Its one genuinely unique ability is that it does not throw on an undeclared name:
4
    typeof notDeclared === 'undefined'   // true, no error
    notDeclared                          // ReferenceError
5
Which is why it is used for feature detection. Note it does not protect against the temporal dead zone — a let declared later still throws.
let
6
instanceof checks the prototype chain.
    [] instanceof Array          // true
    [] instanceof Object         // true -- Array inherits from Object
    new Date() instanceof Date   // true
    'a' instanceof String        // false -- a primitive, not an object
instanceof
7
Its failure case is worth knowing. It breaks across realms — an iframe, or a Node worker — because each has its own Array constructor:
Array
8
    iframeArray instanceof Array   // false, though it is an array
9
So for arrays, use neither.
    Array.isArray(x)     // works across realms, always correct
10
And for everything else, the reliable check is:
    Object.prototype.toString.call(x)
11
    call([])         // '[object Array]'
    call(null)       // '[object Null]'
    call(new Date()) // '[object Date]'
    call(/x/)        // '[object RegExp]'
12
Verbose, and it distinguishes what neither operator can.
13
The practical set.
    a primitive      typeof
    an array         Array.isArray
    null             x === null
    a class instance instanceof, when realms are not involved
    anything else    Object.prototype.toString.call
14
What the interviewer is probing.1. "What does typeof null return and why?" Probing: the historical bug. Stalls: "null." Moves up: "object" — a bug from the first implementation that cannot be fixed without breaking the web.
15
2. "Why can instanceof fail across iframes?" Probing: realms. Stalls: "It cannot." *Moves up:* each realm has its own Array constructor, so an array from an iframe fails instanceof Array; Array.isArray works.
16
3. "How do you reliably identify an array?" Probing: the right tool. Stalls: "typeof." Moves up: Array.isArray — typeof returns "object" for arrays, null and everything non-primitive.
17
4. "What does typeof return for an undeclared variable?" Probing: the safe case. Stalls: "ReferenceError." Moves up: "undefined" — typeof is the one operation that does not throw on an undeclared name.