null vs undefined.
Two nothings. Different meanings.
Both mean "no value." But they mean it differently. undefined is JavaScript's default — a variable that was never assigned, a missing argument, an absent property. null is your default — a value you set explicitly to mean "nothing here." One is automatic, the other is intentional. This page covers the difference, the check patterns, the typeof null quirk, and why ?? is almost always better than ||.
Short answer: undefined = not assigned by JavaScript. null = explicitly set to "nothing" by you. Check for both with value == null (the one accepted use of ==). Check for null specifically with value === null. typeof null === 'object' is a historical bug — don't rely on typeof to detect null. Use ?? (nullish coalescing) for defaults — it only triggers on null/undefined, not 0 or ''.
✅ When each appears
JavaScript gives you undefined. You give null.
undefined (automatic)
Uninitialized variable. Missing function argument. Non-existent property. Function with no return. Array index out of bounds.
null (intentional)
const user = null; — "no user yet." document.getElementById('missing') returns null. JSON null parses to null.
Both are falsy
if (value) skips both. value ? a : b treats both as false. !value is true for both.
Both are primitives
typeof undefined === 'undefined'. typeof null === 'object' (historical bug).
✅ When each appears in practice
The sources of both values.
// === undefined sources ===
let a; // never assigned
console.log(a); // undefined
function f(x) { return x; }
console.log(f()); // undefined (missing arg)
const obj = {};
console.log(obj.missing); // undefined (no property)
function g() {}
console.log(g()); // undefined (no return)
const arr = [1, 2, 3];
console.log(arr[99]); // undefined (out of range)
// === null sources ===
const user = null; // explicit "nothing"
console.log(user); // null
const el = document.getElementById('does-not-exist');
console.log(el); // null
const data = JSON.parse('{"a": null}');
console.log(data.a); // null (JSON null)
Summary: undefined is JavaScript's default: → variables not yet assigned → missing function arguments → missing object properties → functions without a return → array indices out of bounds → the value of 'delete obj.prop' null is always explicit: → you write null in your code → some DOM APIs return null → JSON.parse produces null for JSON null → some APIs return null (databases, fetch) You rarely write null in JS. You frequently receive null from APIs. And you frequently encounter undefined from your own code. Both are "empty," but the source differs.
✅ How to check for them
The three patterns, and which to use when.
const v1 = null; const v2 = undefined; const v3 = 0; const v4 = ''; const v5 = false; // Check for EITHER null or undefined console.log(v1 == null); // true console.log(v2 == null); // true console.log(v3 == null); // false console.log(v4 == null); // false console.log(v5 == null); // false // Check for ONLY null console.log(v1 === null); // true console.log(v2 === null); // false // Check for ONLY undefined console.log(v2 === undefined); // true console.log(v1 === undefined); // false // Check for existence (variable may not exist) console.log(typeof undeclaredVar === 'undefined'); // true (no error) // Modern default — nullish coalescing console.log(v1 ?? 'default'); // 'default' console.log(v3 ?? 'default'); // 0 (not nullish)
Pattern 1: value == null
→ true for null AND undefined
→ false for 0, '', false, NaN, {}, []
→ the one accepted use of ==
→ use for: "is this value missing?"
Pattern 2: value === null
→ true only for null
→ use for: "was this explicitly set to nothing?"
Pattern 3: value === undefined
→ true only for undefined
→ use for: "was this never assigned?"
→ WARNING: if the variable doesn't exist,
this throws ReferenceError
Pattern 4: typeof value === 'undefined'
→ true if the variable doesn't exist OR is undefined
→ use for: existence checks (no ReferenceError)
Pattern 5: value ?? 'default'
→ returns 'default' only if value is null or undefined
→ unlike ||, doesn't trigger on 0, '', false
→ use for: defaults (almost always correct)
Which to use:
"Is this null or undefined?" → value == null
"Is this specifically null?" → value === null
"Does this variable exist?" → typeof value !== 'undefined'
"Default if missing?" → value ?? fallback
✅ The ?? vs || distinction
Why ?? is almost always the right default.
// The problem with ||
function getCount(value) {
return value || 10;
}
console.log(getCount(0)); // 10 — WRONG. 0 is valid.
console.log(getCount('')); // 10 — WRONG. '' might be valid.
console.log(getCount(false)); // 10 — WRONG. false is valid.
console.log(getCount(null)); // 10 — correct
console.log(getCount(undefined)); // 10 — correct
// The fix: ??
function getCountFixed(value) {
return value ?? 10;
}
console.log(getCountFixed(0)); // 0 — correct
console.log(getCountFixed('')); // '' — correct
console.log(getCountFixed(false)); // false — correct
console.log(getCountFixed(null)); // 10 — correct
console.log(getCountFixed(undefined)); // 10 — correct
|| triggers on ANY falsy value: 0, '', false, NaN, null, undefined ?? triggers ONLY on nullish values: null, undefined This matters when 0, '', or false are valid values: ❌ || for default count → returns 10 when 0 ✅ ?? for default count → returns 0 when 0 ❌ || for default price → returns 10 when 0 ✅ ?? for default price → returns 0 when 0 ❌ || for default enabled → returns true when false ✅ ?? for default enabled → returns false when false Rule: use ?? for defaults, unless you specifically want to replace all falsy values. The most common bug: "0 becomes the default." It happens because 0 is falsy. ?? fixes it. Modern JavaScript code uses ?? almost exclusively for defaults. || is reserved for cases where you genuinely want to replace any falsy value (rare).
Don't use typeof to check for null. typeof null === 'object' is a historical bug that can't be fixed without breaking the web. If you write if (typeof value === 'object') expecting to detect an object, null passes the test. The fix: check for null explicitly with value === null, or check value !== null && typeof value === 'object'. This is one of the most common typeof pitfalls. Use === for primitives, typeof only for distinguishing between types where the bug doesn't matter (like checking whether a variable exists).
⚠️ Common mistakes
The null/undefined mistakes that cost real time.
typeof to check for nulltypeof null === 'object'. Fix: value === null.
|| for defaultsReplaces 0, '', false. Fix: ??.
obj.foo.bar throws if foo is undefined. Fix: obj.foo?.bar.
null === undefined is false. Fix: value == null for both.
Use null to explicitly clear. Fix: value = null.
== against other valuesvalue == '' is true for 0 too. Fix: use === for everything except null checks.
typeof for existence checksOk — but doesn't catch null. Fix: combine with !== null.
undefined properties are dropped, null are kept. Fix: use null for explicit "nothing" in JSON.
❓ Frequently asked
What is the difference between null and undefined?
undefined means a value was never assigned — it's the default for uninitialized variables, missing function arguments, and missing object properties. null is an intentional absence — a value you assign explicitly to mean 'no value.' undefined is set by JavaScript; null is set by you. Both are falsy, both are primitives, and both are usually checked with the same pattern.
Should I use null or undefined?
Use undefined for 'not yet set' — leave the default. Use null when you need to explicitly clear a value. In practice, most modern code uses undefined as the default and null only when interfacing with APIs that return null. The pragmatic rule: don't worry about it much — the important thing is to handle both when checking.
How do I check for null or undefined?
The shorthand: value == null is true for both null and undefined, false for everything else. This is the only widely accepted use of ==. The explicit version: value === null || value === undefined. Both work. For null specifically: value === null. For undefined specifically: value === undefined. Use the right check for the case.
Is undefined the same as not defined?
No. 'Not defined' means the variable doesn't exist — accessing it throws a ReferenceError. 'undefined' means the variable exists but has no value. The typeof operator is the safe check: typeof x === 'undefined' works whether x exists or not. Just x === undefined throws if x was never declared.
What is nullish coalescing (??)?
?? is the nullish coalescing operator. a ?? b returns a if a is NOT null and NOT undefined, otherwise returns b. It's like || but only triggers on null/undefined, not on 0, '', false, or NaN. Use ?? when you only want to replace null/undefined. Use || when you want to replace any falsy value.
Why does typeof null return 'object'?
It's a bug in the original JavaScript implementation, and it can't be fixed without breaking the web. In the first version, values were represented with a type tag. Objects had type tag 0, and null was represented as a null pointer (all zeros), which has type tag 0. So typeof null === 'object'. To check for null, use value === null, not typeof.
🔗 Continue learning
Next in this series: