A 1995 Netscape shortcut made 'typeof null' return 'object' forever
In 1995, Brendan Eich prototyped JavaScript in ten days. Values were stored with a type tag in their lowest bits; objects were tagged as 000. Because null was represented as the null pointer 0x00, its tag evaluated to zero, causing typeof null to return 'object'. When the TC39 committee later proposed fixing this bug, the fix was rejected because it would have broken millions of existing websites.
The Ten-Day Origin of a Permanent Quirk
In May 1995, Brendan Eich developed the initial prototype of JavaScript for Netscape Communications under an unforgiving deadline. Tasked with creating a lightweight scripting language for the Netscape Navigator browser in just ten days, Eich had to make rapid architectural decisions. The resulting language borrowed concepts from Scheme, Self, and Java, but its underlying implementation was assembled directly in C to meet delivery milestones for the upcoming browser release.
Under such compressed timelines, language designers rely on pragmatic conventions inherited from their implementation language. In C, memory management and data structures are heavily optimized around machine words and raw pointers. The architectural shortcuts taken to represent variable values efficiently in 1995 laid the foundation for JavaScript's execution model. These quick design choices became permanently embedded in the runtime environment when the web exploded in popularity soon after.
Type Tags and Pointer Representations in Memory
To keep memory usage low and execution fast, early JavaScript engines stored values using a tagged pointer system. In 32-bit systems, memory addresses are aligned along specific byte boundaries, which means the lowest bits of an allocated pointer are consistently zero. Rather than storing a separate metadata structure for every variable, the engine repurposed these lowest bits as a type tag to encode what kind of value a variable held.
Under this binary encoding scheme, values were categorized using the lowest three bits. A tag of 000 indicated an object reference, identifying a pointer to a structured block of memory. Other bit patterns marked integers, floating-point numbers, booleans, and strings. When the engine evaluated a value at runtime, it read these tag bits to determine the value's type without needing to inspect the underlying data structure.