null
Learn JavaScript null as intentional nothing, see APIs that return it, avoid property errors, and predict its math, JSON, and default behavior.
- 01Use null intentionallySet
nullwhen code deliberately means no selected item, no session, no winner, or no result. - 02Recognize null from APIsKnow the common DOM, storage, regular expression, JSON, and prototype APIs that return
null. - 03Avoid null bugsCheck with
value === null, optional chaining, and??, and predict math, comparison, JSON, and default behavior.
null means intentionally nothing
null is JavaScript's value for a deliberate empty place. It does not mean “the code forgot.” It means your code, or an API you called, put a clear sign on the spot: there is no value here right now.
null is a primitive value that means intentionally nothing. Use it when the emptiness is part of the program's message, then check for it before you read properties.
Imagine a classroom chart. One chair has a card saying “reserved: nobody.” That is honest emptiness: the teacher chose that chair to have no student. Another chair has no card at all; maybe nobody has assigned it yet. That second chair is closer to undefined.
- In real life: A seat with a card saying reserved: nobody
- In JavaScript: A variable deliberately set to
null - In real life: A seat nobody has assigned yet
- In JavaScript: A variable or property that is
undefined - In real life: The card is honest about the limit
- In JavaScript: The code should check before using the missing thing
Where the analogy stops: A real seat can be empty for many reasons. JavaScript only gives you values; your naming and checks explain the intention.
The previous undefined lesson focused on values JavaScript hands you when something was not supplied. This lesson focuses on the value you choose when nothing is the right answer.
Assigning null on purpose
STEP THROUGHThe best beginner use of null is state that can be empty by design: no selected item, no logged-in session, no winner yet, or an old reference you no longer want to keep. The next replay uses all three everyday UI cases.
let selectedItem = { id: "lesson-1", title: "Variables" };console.log(selectedItem.title);selectedItem = null;console.log(selectedItem);Null is most useful when code needs to say a value used to exist, or will exist later, but is intentionally empty right now.
script
let session = { user: "Ada" };let winner = null; function clearSelection() { selectedItem = null;} function logout() { session = null;} console.log(selectedItem?.title ?? "nothing selected");clearSelection();logout();console.log(selectedItem === null);console.log(session === null);console.log(winner ?? "no winner yet");Line 6 clears a selected item. Line 10 resets the session after logout. Line 3 starts a game value at null because there is no winner yet. The value is not a bug; it is a message to the rest of the code.
let cachedReport = { rows: new Array(1000).fill("data") };console.log(cachedReport.rows.length);cachedReport = null;console.log(cachedReport);Setting cachedReport to null does not force garbage collection. It only means this variable no longer points at the large object. If nothing else points at that object, the engine can reclaim it later. The memory picture is in Stack & heap.
APIs that return null
EXAMPLESMany APIs use null as their “nothing found” answer. The DOM examples run with a tiny page that has a #save button but no #missing, no .none, and no .panel ancestor.
const missingById = document.getElementById("missing");const missingBySelector = document.querySelector(".none");const button = document.querySelector("#save");const missingAncestor = button.closest(".panel"); console.log(missingById);console.log(missingBySelector);console.log(missingAncestor);Lines 1 and 2 search the document. Line 4 asks the button for a matching ancestor. Each miss prints null because the API deliberately reports “no matching element.”
console.log("abc".match(/z/));console.log(/z/.exec("abc"));console.log(localStorage.getItem("missing"));console.log(JSON.parse("null"));console.log(Object.getPrototypeOf(Object.prototype));Regular expression misses, a missing storage key, the JSON literal null, and the end of the prototype chain all produce real null values.
const answer = prompt("Pick a name");console.log(answer);This prompt example is shown but not runnable in the lesson, because the result depends on pressing Cancel in a browser dialog. Cancel returns null; submitting text returns a string.
console.log([1, 2, 3].find((n) => n > 5));console.log(new Map([["name", "Ada"]]).get("age"));console.log("abc".indexOf("z"));find and Map#get use undefined. Older search APIs such as indexOf use -1. Always check the API contract.
Guard before you use it
STEP THROUGHA safe pattern is: return null from the lookup, store the result, then guard with value === null before using properties. Optional chaining and ?? can keep the code compact when a property might also be nullable.
Step through an API-like helper that returns a user object or null, then watch the caller guard, optional-chain, and choose defaults.
script
{ id: 1, name: "Ada", photo: null }, { id: 2, name: "Linus", photo: "linus.png" },]; function findUser(id) { const match = users.find((user) => user.id === id); return match ?? null;} function describeUser(id) { const user = findUser(id); const name = user?.name ?? "Guest"; if (user === null) { return name + ": no account"; } const photo = user.photo ?? "default.png"; return name + ": " + photo;} console.log(describeUser(3));In the missing-user run, line 8 turns undefined from find into null. Line 14 checks exactly for null, so line 15 returns before any unsafe property read can happen. Try Ada to see a real user whose photo is intentionally null.
typeof null is object
typeof null returns "object". That is a famous early JavaScript bug kept for web compatibility. It does not make null a usable object. For the 1995 type-tag story, see Null inside the engine.
const value = null;console.log(typeof value);console.log(value === null);console.log(Object.prototype.toString.call(value));Line 2 is the compatibility quirk. Line 3 is the check you should write: value === null. Line 4 uses the older object-tag helper, which can name null as [object Null] even though typeof cannot.
Reading properties of null throws
A missing property on a real object gives undefined. A property read on null is different: there is no object to read from, so JavaScript throws. V8 prints this message for the next example: TypeError: Cannot read properties of null (reading 'name').
const profile = null;console.log(profile.name);const profile = null;if (profile === null) { console.log("No profile");}console.log(profile?.name ?? "No name");Use the explicit check when you want the clearest beginner code. Use profile?.name ?? "No name" when you want a compact expression that stops safely and then chooses a fallback.
null in math and comparisons
null has one of JavaScript's most memorable conversion tables. Numeric conversion turns null into 0, but loose equality has a special rule that does not make null == 0 true.
console.log(Number(null));console.log(Number(undefined));console.log(null + 1);console.log(null * 3);console.log(null == 0);console.log(null >= 0);console.log(null > 0);console.log(null == undefined);console.log(null === undefined);console.log(null < 1);Lines 1 through 4 are numeric conversion. Lines 5 through 10 compare values. Relational comparisons convert to numbers, so null >= 0 is true, null > 0 is false, and null < 1 is true. Loose equality only treats null like undefined.
Try every operation
PLAYGROUNDPick a value and an operation. The source code stays visible, the result is computed from the selected JavaScript value, and the explanation points out the rule being used.
const value = null;console.log(value + 1);null is intentional nothing. value + 1 gives 1. The `+` operator converts `null` and `undefined` differently: `null` becomes 0, while `undefined` becomes NaN. Strings concatenate.
null is intentional nothing. value + 1 gives 1. The + operator converts null and undefined differently: null becomes 0, while undefined becomes NaN. Strings concatenate.
null in JSON and defaults
JSON keeps null because JSON has a null literal too. Defaults are different: default parameters and destructuring defaults replace undefined, not null. If you want to replace null, use an expression such as ?? or ||.
function greet(name = "friend") { return `Hi, ${name}`;}const { photo = "avatar.png" } = { photo: null }; console.log(JSON.stringify({ photo: null }));console.log(greet(null));console.log(greet(undefined));console.log(photo);console.log(null ?? "fallback");console.log(null || "fallback");Prototype chains end at null
Every ordinary object has a prototype chain. The chain eventually reaches Object.prototype, and that object's prototype is null. That is the end of the chain. JavaScript also lets you create an object whose chain starts at null.
const chainEnd = Object.getPrototypeOf(Object.prototype);console.log(chainEnd); const dictionary = Object.create(null);dictionary.answer = 42;console.log("toString" in dictionary);console.log(dictionary.answer);Object.create(null) makes a very plain dictionary. It has your own keys, but it does not inherit methods such as toString. That is why line 6 prints false.
Does JavaScript give you null, undefined, or something else?
SORTERDifferent APIs use different sentinels for “not found.” Sort these cards by the value the API gives you on a miss.
document.getElementById("missing")document.querySelector(".none")button.closest(".panel") when no ancestor matches"abc".match(/z/)/z/.exec("abc")localStorage.getItem("missing")prompt() when the user cancelsJSON.parse("null")Object.getPrototypeOf(Object.prototype)[].find(...) with no matchnew Map().get('missing')object.missingA function that reaches the end with no return"abc".indexOf("z")document.querySelectorAll(".none")
Sort each API result by the value it gives when nothing is found.
Practical uses
Use null when the empty state is part of the model. A search result can be null before anything is selected. A session can become null after logout. An API can send { "photo": null } to say the user intentionally has no photo. A DOM lookup can return null because no element matches.
The practical habit is always the same: make the intention visible, then guard before using properties. If both null and undefined should fall back, use ??. If only null is allowed, use value === null.
Common misconceptions
- “
nullis an object.” No.typeof nullsays"object"because of history;nullis still a primitive. - “Defaults replace
null.” Default parameters and destructuring defaults replaceundefined, notnull. - “
null == 0becauseNumber(null)is 0.” Loose equality uses a different rule fornull. - “Reading a missing property and reading from
nullare the same.” A missing property givesundefined; reading fromnullthrows. - “Every missing API result is
null.” Some APIs useundefined,-1, or an empty collection.
| Check | null | undefined | 0 | "" |
|---|---|---|---|---|
typeof value | "object" | "undefined" | "number" | "string" |
Boolean(value) | false | false | false | false |
Number(value) | 0 | NaN | 0 | 0 |
value == null | true | true | false | false |
JSON.stringify({ v: value }) | {"v":null} | {} | {"v":0} | {"v":""} |
function f(x = "d") { return x; } | f(null) is null | f(undefined) is "d" | f(0) is 0 | f("") is "" |
Practice exercises
6 EXERCISESPredict the three console lines in order.
console.log(Number(null));
console.log(null + 1);
console.log(null == undefined);The three outputs are 0, 1, and true.
Replace profile.name with a safe expression that prints No name.
const profile = null;
console.log(profile.name);const profile = null;
console.log(profile?.name ?? "No name");profile?.name avoids the throw, and ?? "No name" supplies the fallback.
What value does this failed string match print?
console.log("abc".match(/z/));"abc".match(/z/) returns null because the regular expression found no match.
Predict both output lines.
function greet(name = "friend") {
return "Hi, " + name;
}
console.log(greet(null));
console.log(greet(undefined));greet(null) prints Hi, null; greet(undefined) prints Hi, friend.
Which value should a UI store after the user clicks Clear selection?
let selectedItem = { title: "JavaScript basics" };
selectedItem = null;
console.log(selectedItem);Set the variable to null when the user intentionally clears the selection.
What does the "toString" in dictionary line print?
const dictionary = Object.create(null);
dictionary.answer = 42;
console.log("toString" in dictionary);
console.log(dictionary.answer);The first line prints false; the dictionary does not inherit toString.
Check your understanding
8 QUESTIONSQuestion 1 of 8What does
nullmean in beginner JavaScript code?Choose an answer to see the explanation.
Question 2 of 8What does this print?
Read the code, then predictconsole.log(typeof null);Choose an answer to see the explanation.
Question 3 of 8What error does this code throw in V8-based browsers and Node?
Read the code, then predictconst profile = null; console.log(profile.name);Choose an answer to see the explanation.
Question 4 of 8What do these math and comparison lines print?
Read the code, then predictconsole.log(null + 1); console.log(null >= 0);Choose an answer to see the explanation.
Question 5 of 8What do these equality checks print?
Read the code, then predictconsole.log(null == 0); console.log(null == undefined); console.log(null === undefined);Choose an answer to see the explanation.
Question 6 of 8What JSON string does this print?
Read the code, then predictconsole.log(JSON.stringify({ photo: null, nickname: undefined }));Choose an answer to see the explanation.
Question 7 of 8What does the default parameter example print?
Read the code, then predictfunction greet(name = "friend") { return "Hi, " + name; } console.log(greet(null)); console.log(greet(undefined));Choose an answer to see the explanation.
Question 8 of 8What does optional chaining plus nullish coalescing print?
Read the code, then predictconst user = null; console.log(user?.name ?? "Guest");Choose an answer to see the explanation.
Key takeaways
nullis a primitive value meaning intentionally nothing.- Your code or an API puts
nullthere on purpose. - Check exact
nullwithvalue === null. typeof nullis"object"for historical compatibility; do not treatnulllike an object.- Reading a property of
nullthrows; guard or use optional chaining. - Numeric operations convert
nullto0, butnull == 0is stillfalse. - JSON keeps
null; default parameters and destructuring defaults do not replace it.
Final definition: null is JavaScript's primitive value for an intentionally empty result or state.
Up next: Booleans, null & undefined compares all three side by side. For the engine view, visit Null inside the engine.