All articles

Why does typeof null return "object" in JavaScript?

It is a bug from 1995 that can never be fixed. Here is the actual cause, and what to use instead when you need to check for null.

· 3 min read

typeof null        // "object"
typeof undefined   // "undefined"

null is not an object. It is a primitive, sitting alongside undefined, numbers, strings, booleans, symbols and bigints. So why does typeof disagree?

The actual cause

In the original 1995 JavaScript implementation, values were stored as a pair: a small type tag, and the data itself. The tag occupied the low bits of a 32-bit word:

Tag Type
000 object — the data is a reference
001 integer
010 double
100 string
110 boolean

null was represented as the null pointer — all bits zero. Its type tag was therefore 000, which is indistinguishable from the tag for "object".

typeof read the tag and answered accordingly. It was not a special case or an oversight in the operator; null genuinely looked like an object to the code doing the checking.

Why it was never fixed

It was proposed. In 2013, during ES6 discussions, a change was floated to make typeof null === "null". It was rejected.

The reason is that a very large amount of code in the wild is written like this:

if (typeof value === 'object') {
  // assume it might be null and check
  if (value !== null) { ... }
}

Changing the return value would silently alter which branch that code takes on millions of pages, most of which nobody maintains any more. JavaScript's commitment to not breaking the web means a wart this small stays permanently.

What to use instead

For a null check, compare directly:

value === null

To catch both null and undefined, use loose equality with null. This is the one case where == is genuinely the right tool, because it matches exactly those two values and nothing else:

value == null   // true for null and undefined, false for 0, '', NaN

To tell a real object from null:

function isObject(value) {
  return typeof value === 'object' && value !== null
}

And if you want an accurate type for anything at all:

function typeOf(value) {
  return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
}

typeOf(null)        // "null"
typeOf([])          // "array"
typeOf(new Date())  // "date"
typeOf(/x/)         // "regexp"

That form reads an internal tag that, unlike typeof, does distinguish these cases.

The related gotcha

typeof has a second surprise that shows up in the same interview:

typeof []           // "object"
typeof function(){} // "function"

Arrays report as objects, which is technically correct — an array is an object — but rarely what you want. Use Array.isArray().

Functions report as "function" even though they are objects too, because typeof special-cases anything callable.

Why interviewers ask

On its own, this is trivia. What it actually probes is whether you know that null and undefined are distinct, and whether you reach for === null rather than trusting typeof. A candidate who explains the tagged-union cause has usually read about the language rather than only used it — which is the real signal.

Put it into practice

106 JavaScript questions, each with an explanation. Find out whether this actually stuck.

Take the JavaScript quiz

Related reading