A variable holding nothing is less simple than it sounds. There is the nothing you decided on, written down to signal that a slot is empty, and the nothing you inherited, a value nobody ever filled in. JavaScript is one of the few languages that separates the two.
Definition
null is a primitive value meaning the deliberate absence of a value. It is a reserved keyword: written as is, lowercase, without quotes, and unusable as a variable name.
Everything hangs on one word, deliberate. Nobody stumbles on null by accident: it is there because somebody wrote it, or because a function chose to return it to report that it found nothing.
let currentUser = null; // nobody yet
// A failed lookup returns null, not an error
const button = document.querySelector(".missing");
console.log(button); // nullThose two lines cover the everyday use: a starting value filled in later, and a search that came back empty.
null against undefined
Both values say there is nothing there, but the first is a decision and the second an observation.
| Question | null | undefined |
|---|---|---|
| Who put it there | You, or a function | The JavaScript engine |
| What it means | Empty on purpose | Never filled in |
Result of typeof | "object" | "undefined" |
Kept by JSON.stringify | Yes | No, the key vanishes |
That last row matters as soon as data travels to a server. Sending { city: null } asks to clear the city. Sending { city: undefined } sends no field at all, and the server keeps the old value.
The most famous bug in the language
console.log(typeof null); // "object"
console.log(null instanceof Object); // falseThe two lines contradict each other, and the second one is right. It is an original defect, inherited from the first implementation of the language in 1995, never fixed because correcting it would break entire websites.
Practical consequence: typeof value === "object" is not enough to recognize an object. It needs a detour through Object.prototype.toString.call(value).
Testing it properly
Three forms show up regularly, and they do not answer the same question.
const v = null;
v === null // true: null only
v == null // true: null OR undefined
v ?? "fallback" // "fallback": the replacement valueThe third one is the everyday choice: Nullish coalescing (??) handles null and undefined together, which is almost always what you need. Be wary of ordering comparisons though, which convert null into zero where Loose equality (==) does not.
Frequently asked questions
Should a variable be initialized to null or left empty?
Use null when emptiness is part of the expected scenario, a user who has not signed in for instance. Leave the variable unassigned when it gets filled a line or two later anyway. The first form documents an intention, the second reports that nothing has happened yet.
Why does an API return null instead of dropping the field?
Because the two answers carry different meanings. A field present and set to null states that the information was looked up and does not exist. A missing field leaves doubt: maybe it was not requested, maybe this version does not expose it. Well-designed APIs keep the field.
How do I avoid the "cannot read properties of null" error?
It happens when a property is read on an empty value. Optional chaining (?.) defuses it in one line: element?.textContent returns undefined instead of crashing the page. On older code, an if (element) before the read does the same job.