Free lesson · JavaScript Basic to Advance
null and undefined
Two Ways to Say "Nothing"
JavaScript has two different values that both mean "no value here." They're called null and undefined. To beginners, they look interchangeable. To experienced JavaScript developers, they mean very different things. Confusing them is one of the most common signals that a candidate has surface-level knowledge of the language.
This Topic exists to make the distinction crystal clear. By the end, you should never be uncertain about which one you're looking at or which one to use.
The Short Version
undefined means "no value has been assigned yet." JavaScript uses this automatically when a variable exists but hasn't been given a value, or when a function doesn't return anything explicitly.
null means "I deliberately put nothing here." You write null on purpose to say "this slot is intentionally empty."
The difference is intent. undefined happens automatically. null is something you choose.
let cityWhereILive; // declared but not assigned
console.log(cityWhereILive); // undefined
let cityWhereIGrewUp = null; // I deliberately said: I'm not specifying this
console.log(cityWhereIGrewUp); // null
In the first case, JavaScript filled in undefined because I didn't assign anything. In the second case, I explicitly wrote null to communicate "I'm choosing to leave this empty."
Where undefined Comes From
JavaScript assigns undefined automatically in several specific situations. You should be able to recognize each one.
A variable declared without an assignment:
let userName;
console.log(userName); // undefined
A function parameter that wasn't passed:
function greet(name) {
console.log(name);
}
greet(); // undefined — no argument was passed
A function that doesn't explicitly return anything:
function doNothing() {
// no return statement
}
const result = doNothing();
console.log(result); // undefined
A property that doesn't exist on an object:
const user = { name: "Olena" };
console.log(user.age); // undefined — no 'age' property
An array index that's out of bounds:
const arr = ["a", "b", "c"];
console.log(arr[10]); // undefined
In every one of these cases, JavaScript chose undefined for you. You didn't write it anywhere. It appeared because something was missing.
Interactive animation: Two very different origins - undefined arrives on its own, null is placed on purpose.
Where null Comes From
null doesn't appear automatically. It only exists in your code when you write it yourself, or when something else (a library, an API response, a database) writes it for you.
let selectedUser = null; // explicitly: no user is currently selected
function findUser(id) {
// search logic here...
// if no user found, return null deliberately
return null;
}
const result = findUser(999);
console.log(result); // null
The pattern in that second example is common: a function that searches for something returns null to communicate "I looked, and there isn't one." Returning null is a deliberate signal — it's different from a function returning undefined (which usually means "I forgot to return something" or "the function doesn't return a value").
graph LR
A[undefined] --> B[JavaScript assigned it<br/>automatically]
A --> C[Means: no value has been<br/>set yet]
D[null] --> E[You wrote it<br/>on purpose]
D --> F[Means: deliberately<br/>empty]
style A fill:#ef4444,color:#fff
style D fill:#7c3aed,color:#fff
This diagram shows the conceptual difference between undefined and null. Undefined is something JavaScript assigns automatically when no value has been set yet. Null is something you write on purpose when you want to deliberately communicate that a slot is empty. The difference is intent: undefined is the default state, null is a chosen state.
How to Check for Each One
You'll often need to test whether a value is null, undefined, or both. Here are the patterns to use.
Checking for undefined specifically:
let x;
console.log(x === undefined); // true
console.log(typeof x === "undefined"); // true (also works)
Checking for null specifically:
let y = null;
console.log(y === null); // true
Note: typeof null returns "object" (the famous bug from Module 1), so you can't use typeof to detect null. Use === null instead.
Checking for either one (the common case):
function check(value) {
if (value === null || value === undefined) {
console.log("Empty (null or undefined)");
} else {
console.log("Has a value");
}
}
check(undefined); // Empty
check(null); // Empty
check(0); // Has a value
check(""); // Has a value
check("Olena"); // Has a value
Modern JavaScript has a shorter way to write the value === null || value === undefined check using the nullish coalescing operator ??, which we'll cover in Module 10. For now, the explicit comparison is clear and correct.
Why == Is Special With null and undefined
Here's a quirk you need to know. The loose equality operator == treats null and undefined as equal to each other but to nothing else:
console.log(null == undefined); // true
console.log(null == 0); // false
console.log(undefined == 0); // false
console.log(null == ""); // false
console.log(undefined == false); // false
This is the one place where == behaves in a way many developers find useful. Some style guides actually allow value == null as a shortcut for checking both null and undefined at once.
But — and this is important — using == for anything else is dangerous, for reasons we'll cover in Topic 2.7 on equality. The general rule remains: prefer ===. The == null shortcut is a deliberate, narrow exception that some teams allow.
Interactive animation: How to actually test for nothing - typeof says "object" for null, while x == null catches null and undefined.
When to Use Which
Some practical guidelines:
Use undefined when you're letting JavaScript's default behavior do its thing. Don't explicitly write undefined in your code — let it appear naturally when variables are unassigned or functions don't return values.
Use null when you need to actively communicate "this is empty on purpose." For example:
// In a user object, null clearly says "no preference set"
const user = {
name: "Olena",
preferredLanguage: null, // we asked, they didn't answer
birthDate: null // they chose not to share
};
console.log(user.preferredLanguage);
console.log(user.middleName); // undefined — we didn't even ask
The difference between preferredLanguage: null and user.middleName (which is undefined) is meaningful. The first one says "we asked the user, they didn't provide one." The second one says "we never tried to set this." That distinction matters in real systems.
Common Pitfalls
Warning: The three biggest mistakes around null and undefined.
Treating them as interchangeable. They're not.
undefinedmeans "wasn't set."nullmeans "deliberately empty." Mixing them up muddies the meaning of your code and confuses code reviewers.Using
typeofto check fornull.typeof nullreturns"object", not"null". To check for null, usevalue === null. Thetypeofoperator is essentially broken for this one case.Forgetting that accessing a missing property gives you
undefined. Code likeif (user.profile.age > 18)will throw an error ifuser.profileis undefined, because you can't read.agefrom undefined. Modern JavaScript provides optional chaining (user.profile?.age) to handle this safely — covered in Module 10.
Interactive animation: Reading through a missing property - optional chaining stops the crash, and a default replaces the undefined.
Why This Matters in Interviews
Interview: "What is the difference between null and undefined?" is one of the most common JavaScript interview questions. The expected answer covers three things:
undefinedis assigned automatically;nullis assigned deliberatelytypeof undefinedis"undefined", buttypeof nullis"object"(a historical bug)- They are loosely equal (
null == undefinedis true) but not strictly equal (null === undefinedis false)A candidate who can explain all three points has signaled real depth. A candidate who says "they're basically the same" has signaled the opposite.
Topic 2.8 — Interview Lens: Type Coercion Questions — covers the deeper puzzles around null and undefined, including the loose equality comparisons and the
typeof nullhistory question.
Try It
Exercise: Predict the output of each line. Then run them to check.
let a; let b = null; console.log(a); console.log(b); console.log(typeof a); console.log(typeof b); console.log(a === b); console.log(a == b); console.log(a === null); console.log(b === undefined); function noReturn() {} console.log(noReturn()); const obj = {}; console.log(obj.missing);The two
==and===comparisons should especially get your attention. The pattern:==says they're equal,===says they're not. Both are correct under their own rules.