Why typeof null Returns Object in JavaScript

In JavaScript, executing typeof null unexpectedly returns "object" instead of "null". This behavior is not an intentional design feature, but a historical bug originating from the language’s initial release in 1995. Although it has long been recognized as a flaw in the language specifications, it remains unfixed to preserve backward compatibility across the web.

The Technical Reason Behind the Bug

In the first implementation of JavaScript, values were stored in 32-bit units composed of a type tag and the actual value data. The type tag occupied the lower 1 to 3 bits of the unit to identify what kind of data was being held.

The runtime defined the following type tags: * 000: Object * 1: Int (a 31-bit signed integer) * 010: Double (a double-precision float) * 100: String * 110: Boolean

Because null was represented as the null pointer (0x00 in C), it was represented by all zeros across the entire 32-bit block. When the typeof operator checked the type tag of null, it read the first three bits—000—and incorrectly identified the value as an object.

Why the Bug Was Never Fixed

A proposal was submitted to fix this behavior in ECMAScript (the standard that defines JavaScript) by making typeof null return "null".

However, the proposal was rejected. Changing the behavior of typeof null would introduce breaking changes to thousands of existing websites and legacy applications that inadvertently rely on typeof null === 'object' for their logic. As a fundamental principle of JavaScript evolution, changes that “break the web” are strictly avoided.

How to Correctly Check for Null

Because typeof cannot differentiate between an actual object and null, developers should use the strict equality operator (===) or Object.is() to check for null values:

const value = null;

// Incorrect
console.log(typeof value === 'object'); // true (false positive)

// Correct
console.log(value === null); // true
console.log(Object.is(value, null)); // true

To verify if a value is a genuine object and not null, check both conditions simultaneously:

function isRealObject(val) {
  return typeof val === 'object' && val !== null;
}