Why is object considered a data type in JavaScript, and why does typeof null return “object”?

Summary

This postmortem explains why JavaScript treats object as a data type, and why the infamous typeof null === "object" behavior exists. These behaviors often confuse developers coming from class‑based languages like Java, but they stem from historical design decisions and how JavaScript represents values internally.

Root Cause

The root causes are twofold:

  • JavaScript’s type system is value‑based, not class‑based. “Object” is a fundamental data type, not a structure.
  • A bug in the original 1995 implementation caused null to be tagged as an object, and that bug became permanent for backward compatibility.

Why This Happens in Real Systems

Real-world systems—especially those created under time pressure—often carry legacy decisions forward:

  • Early design constraints force developers to choose simple internal representations.
  • Backward compatibility becomes more important than correctness once millions of programs rely on the behavior.
  • Fixing the bug would break the web, so the bug becomes part of the spec.

Real-World Impact

These quirks lead to:

  • Incorrect type checks when developers rely on typeof.
  • Unexpected behavior in conditionals, especially when checking for objects vs. null.
  • Hard-to-debug issues when integrating with libraries that assume strict type semantics.

Example or Code (if necessary and relevant)

console.log(typeof {});     // "object"
console.log(typeof null);   // "object" (legacy bug)
console.log(null === Object(null)); // false

How Senior Engineers Fix It

Experienced engineers avoid relying on typeof for object detection and instead use safer patterns:

  • Use strict null checks:
    value !== null && typeof value === "object"
  • Use Array.isArray() for arrays.
  • Use Object.prototype.toString.call(value) for precise type detection.
  • Normalize inputs early to avoid ambiguous states.

They also understand that language quirks must be worked with, not fought.

Why Juniors Miss It

Junior developers often miss this because:

  • They assume JavaScript behaves like Java or C#, where “object” is a structure, not a primitive type category.
  • They expect typeof to be reliable for all values.
  • They don’t yet recognize how historical bugs become permanent features in widely deployed languages.
  • They haven’t encountered enough real-world systems to see how compatibility outweighs correctness in language evolution.

Leave a Comment