NaN, null, undefined
The Three Empty Parking Spaces
LinkedIn Hook
typeof nullis"object". It has been since 1995 — and it will stay that way forever.
NaN !== NaN. The only value in JavaScript that isn't equal to itself.
isNaN("hello")returnstrue. ButNumber.isNaN("hello")returnsfalse. One of them has a bug. Can you guess which?These three values —
NaN,null,undefined— look similar but behave completely differently. Mixing them up is how bugs silently survive to production.In this lesson you'll learn when each one appears, why
typeof nullis a 30-year-old bug, the critical difference betweenisNaN()andNumber.isNaN(), and the one-liner that reliably checks for both null and undefined.If an interviewer asks "what's the difference between null and undefined?" — this lesson gives you the answer they're really testing for.
Read the full lesson -> [link]
#JavaScript #InterviewPrep #NaN #NullVsUndefined #Frontend #CodingInterview #WebDevelopment
What You'll Learn
- Exactly when
undefined,null, andNaNeach appear — and what they really mean - Why
typeof nullis"object"(and why it will never be fixed) - How to reliably check for
NaNand for "null or undefined" in one expression
Three Empty Parking Spaces
Think of a variable as a parking space. undefined means the space was reserved but no car has parked yet. null means someone deliberately put a "space intentionally empty" sign. NaN means someone tried to park a banana — the system expected a car (number) but got something nonsensical.
When Each Appears
// undefined -- "declared but not assigned"
let x;
console.log(x); // undefined
function greet(name) {
console.log(name); // undefined if no argument passed
}
greet();
const obj = { a: 1 };
console.log(obj.b); // undefined -- property doesn't exist
function noReturn() { /* no return statement */ }
console.log(noReturn()); // undefined
// null -- "intentionally set to nothing"
const user = null; // we explicitly set this
// Common API pattern: "no result found"
document.getElementById("nonexistent"); // null
// Clearing a reference
let cache = { data: [1, 2, 3] };
cache = null; // intentionally cleared
// NaN -- "failed numeric operation"
const result = parseInt("hello"); // NaN
const math = 0 / 0; // NaN
const bad = undefined + 1; // NaN
const oops = Math.sqrt(-1); // NaN
typeof Results — The Historical Bug
typeof undefined; // "undefined" -- correct
typeof null; // "object" -- BUG! (since 1995, never fixed)
typeof NaN; // "number" -- technically correct (NaN is a numeric type)
// Why typeof null === "object":
// In the original JS engine, values were stored as a type tag + value.
// Objects had type tag 0. null was the NULL pointer (0x00).
// So null's type tag was also 0, making typeof think it's an object.
// It's been a known bug since 1995 but can't be fixed without
// breaking millions of websites.
Equality Comparisons Between Them
// null and undefined are loosely equal to each other
null == undefined; // true (special spec rule)
null === undefined; // false (different types)
// null and undefined are NOT equal to anything else with ==
null == 0; // false
null == ""; // false
null == false; // false
undefined == 0; // false
undefined == ""; // false
undefined == false; // false
// NaN is not equal to ANYTHING -- not even itself
NaN == NaN; // false
NaN === NaN; // false
NaN != NaN; // true -- the only value where this is true!
Number.isNaN vs Global isNaN
// Global isNaN() -- COERCES the argument to number first, then checks
isNaN(NaN); // true -- correct
isNaN("hello"); // true -- MISLEADING! "hello" isn't NaN, but
// Number("hello") is NaN, so it returns true
isNaN(undefined); // true -- Number(undefined) is NaN
isNaN("123"); // false -- Number("123") is 123, not NaN
isNaN(""); // false -- Number("") is 0, not NaN
// Number.isNaN() -- NO coercion, checks if the value IS ACTUALLY NaN
Number.isNaN(NaN); // true -- correct
Number.isNaN("hello"); // false -- "hello" is a string, not NaN
Number.isNaN(undefined); // false -- undefined is not NaN
Number.isNaN(123); // false -- 123 is not NaN
// ALWAYS use Number.isNaN() -- the global isNaN is essentially broken
Checking for null and undefined
// Check for null specifically
value === null;
// Check for undefined specifically
value === undefined;
typeof value === "undefined"; // safe even if variable is undeclared
// Check for either null or undefined
value == null; // true for both null AND undefined (the one good use of ==)
value == null; // equivalent to: value === null || value === undefined
// Modern: nullish coalescing and optional chaining
const name = user?.profile?.name ?? "Unknown";
Common Mistakes
- Using the global
isNaN(x)for input validation — it coerces first, soisNaN("hello")istrue. UseNumber.isNaN(x)instead. - Checking
value == null || value == undefined— that's redundant.value == nullalready matches both (and only both). - Treating
undefinedas something you should manually assign. Let JavaScript produceundefined; usenullwhen you want to say "intentionally empty."
Interview Questions
Q: What is the difference between null and undefined?
undefinedmeans a variable has been declared but not assigned a value -- it's the default state.nullis an explicit assignment meaning "intentionally no value."undefinedis typically assigned by JavaScript, whilenullis assigned by the developer.
Q: Why does typeof null return "object"?
It's a historical bug from JavaScript's first implementation in 1995. Values were stored with type tags, and the tag for objects was
0. Sincenullwas represented as the NULL pointer (0x00), its type tag was also0, sotypeofincorrectly identifies it as"object". This was never fixed to maintain backward compatibility.
Q: What is the difference between isNaN() and Number.isNaN()?
The global
isNaN()coerces its argument to a number first, soisNaN("hello")returnstrue(becauseNumber("hello")isNaN).Number.isNaN()does NOT coerce -- it returnstrueonly if the value is actuallyNaN. Always preferNumber.isNaN().
Q: How can you check if a value is NaN?
Use
Number.isNaN(value). Alternatively,NaNis the only value wherevalue !== valueistrue, so that self-inequality check also works.
Q: Why is NaN !== NaN?
The IEEE 754 floating-point standard defines
NaNas "not equal to anything, including itself." JavaScript inherits that behavior, which is whyNaN === NaNandNaN == NaNboth returnfalse. This self-inequality is actually a useful signature:x !== xistrueonly whenxisNaN.
Q: How do you check if a value is null or undefined in one comparison?
Use
value == null. Because of the spec rule thatnull == undefined, this single check returnstruefor bothnullandundefinedand is equivalent tovalue === null || value === undefined.
Quick Reference — Cheat Sheet
NaN / null / undefined -- QUICK MAP
Meaning:
undefined -> declared, not assigned (JS assigns it)
null -> intentionally empty (YOU assign it)
NaN -> failed numeric operation (type: number)
typeof results:
typeof undefined -> "undefined"
typeof null -> "object" (1995 bug, never fixed)
typeof NaN -> "number"
Equality:
null == undefined -> true (only each other)
null === undefined -> false
NaN == NaN -> false
NaN === NaN -> false
x !== x -> true only when x is NaN
Checking:
Number.isNaN(x) -- the correct NaN check (no coercion)
isNaN(x) -- legacy, coerces: avoid
value == null -- matches null OR undefined in one shot
typeof v === "undefined" -- safe even if v is not declared
user?.x ?? "fallback" -- modern null/undefined-safe access
Previous: Truthy / Falsy -> The Nightclub Bouncer Next: Symbol & BigInt -> The Two Newest Primitives
This is Lesson 8.5 of the JavaScript Interview Prep Course — 14 chapters, 87 lessons.