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)); // trueTo verify if a value is a genuine object and not null,
check both conditions simultaneously:
function isRealObject(val) {
return typeof val === 'object' && val !== null;
}