Lesson 6 · 9 min read

Undefined vs Not Defined

These sound like the same complaint — "there's nothing there" — but JavaScript treats them as two completely different situations, one safe and expected, the other a genuine error. Mixing them up is one of the most common small misunderstandings in the language.

On this page

  1. Concept
  2. Why this matters
  3. The room board — an analogy
  4. undefined — reserved but empty
  5. Not defined — never existed at all
  6. The safe check: typeof on an undeclared variable
  7. null vs. undefined — two different kinds of "nothing"
  8. Where undefined sits among the falsy values
  9. Why JS is called loosely typed
  10. The anti-pattern: don't assign undefined yourself
  11. Real example — traced line by line
  12. See it live — console & DevTools
  13. Common misconceptions
  14. Interview questions

Concept

undefined and “not defined” both sound like “there's nothing here,” but they describe two genuinely different situations in memory:

  • undefined — undefined is a special value that means “this variable exists, but no value has been put in it yet.” Memory was reserved for the name.
  • “not defined” — not a value at all, but an error message. It means this name was never reserved in memory anywhere in scope, because it was never declared. To declare a variable means to create its name with var, let or const.

One is JavaScript telling you “this exists, it's just empty right now.” The other is JavaScript telling you “this doesn't exist, and never has.” Confusing the two is a common mistake, and interviewers like to ask about it.

Why This Matters

  • It follows directly from Lesson 1's memory creation phase. This lesson gives the two possible results of that phase their proper names.
  • Knowing the difference tells you instantly whether a bug is a typo (undeclared variable) or a timing issue (declared but not yet assigned).
  • It teaches a useful safe pattern: checking whether a variable exists with typeof, without risking a crash. typeof is an operator (a built-in word that works on a value) that returns the type of a value as a string.
  • It explains why JavaScript is called a loosely typed language, and what that means in practice.

The Room Board — An Analogy

A reserved-but-empty room vs. a room number that doesn't exist

Picture the hotel's room status board. Room 101 has a slot on that board — it's a real, reserved room — but right now its status card just says “Vacant, not yet assigned a guest.” That's undefined: a real, reserved slot, currently empty.

Now imagine someone asks the receptionist about “Room 999.” There is no slot for Room 999 on the board at all — the hotel was never built with that room. Asking about it doesn't return “vacant,” it gets you told outright: “there is no such room here.” That's “not defined” — not an empty slot, but the total absence of one.

undefined — Reserved But Empty

undefined.js
console.log(guestName); // undefined
var guestName;

During the memory creation phase (Lesson 1), JS reserved a slot for guestName and filled it with the placeholder value undefined — a real value in JavaScript, not an error. The variable exists; it just has no real value yet. (The engine also gives you undefined when you read an object property that does not exist, when you skip an argument in a function call, and when a function has no return value.)

Not Defined — Never Existed At All

not-defined.js
console.log(mysteryGuest); // ReferenceError: mysteryGuest is not defined

mysteryGuest was never declared anywhere in any reachable scope. No memory was ever reserved for it, so referencing it directly throws a ReferenceError. A ReferenceError is the error type JavaScript throws when your code uses a name that it cannot find (or cannot use yet). It stops the program at that line. It is not a value you can read.

Room 101 — on the board
guestNameundefined
status: “Vacant” = undefined
a real slot, just empty right now
Room 999 — not on the board
no such slot exists
= ReferenceError
not defined, ever
One is a real, empty entry. The other was never entered on the board at all. · room board

The Safe Check: typeof On An Undeclared Variable

typeof.js
console.log(mysteryGuest);        // ReferenceError — crashes
console.log(typeof mysteryGuest); // "undefined" — perfectly safe, no crash

typeof is an exception to the ReferenceError rule: checking the type of a variable that was never declared still returns the string "undefined" instead of throwing. This makes typeof a safe way to ask “does this exist?” It is often used to detect whether an optional global, such as a library loaded from a CDN (a server that delivers files, like libraries, to web pages), is present. One limit: typeof still throws for a let or const name that is in the Temporal Dead Zone (Lesson 3). Also, typeof null is "object", an old mistake in the language that was never fixed.

null vs. undefined — Two Different Kinds Of “Nothing”

undefinednull
Who sets itThe engine, automaticallyYou, deliberately, in your own code
Meaning“Not yet assigned”“Intentionally empty”: a value that means “no object here”
Typical useThe default state before assignmentExplicitly clearing or resetting a value on purpose

Both mean “nothing,” but they come from different sides: undefined is what JS gives you by default when it hasn't been told anything yet. null is what you give to JS yourself, on purpose, to say “I know there's nothing here.”

Where undefined Sits Among The Falsy Values

undefined is one of JavaScript's small set of falsy values. A falsy value is a value that counts as false inside a condition (a test, like the one in an if). A value that counts as true is called truthy.

falsy.js
if (undefined) {
  // never runs
}
Falsy values in JavaScript
undefined, null, 0 (and -0), 0n (the BigInt zero), "" (empty string), false, NaN (“Not a Number”, the result of a failed number calculation)

Everything else — including "0" the string, an empty array [], and an empty object {} — is truthy.

falsy · if (…) never runs
undefinednull0""falseNaN
truthy · even these
"0"[]{}" "-1"false"
Six values behave like false inside a condition. Everything else — including the surprising ones on the right — is truthy. · falsy vs truthy

Why JS Is Called Loosely Typed

loose.js
let value = 101;       // number
value = "Room 101";    // now a string
value = true;          // now a boolean
value = undefined;     // now... undefined

The same variable can hold a number, then a string (text), then a boolean (true or false), with no error. A type is the kind of a value, such as number, string or boolean. JavaScript is called loosely typed because a variable's type is not fixed when you declare it. The type belongs to the value that the variable holds right now. (The exact words: types are checked while the program runs, which is dynamic typing, and JavaScript converts types automatically in some cases, for example "5" * 2 gives 10, which is weak typing.) undefined is also a type, with only one value.

step 1 / 4
Code execution phase
value holds a number

typeof value is "number". Nothing about the slot says it must stay one.

loose.js
1let value = 101;
2value = "Room 101";
3value = true;
4value = undefined;
memory · one slot
value101
typeof value"number"
numberstringbooleanundefined
Step through the four assignments. The slot never changes; its type is whatever the current value happens to be. · interactive

The Anti-Pattern: Don't Assign undefined Yourself

anti-pattern.js
// avoid this
var guestName = undefined;

// prefer this instead
var guestName; // naturally undefined, nothing extra needed
// or, if you deliberately want to represent "no value" on purpose:
var guestName = null;

undefined is meant to be the engine's own signal: “nobody has assigned this yet.” If you write = undefined yourself, the signal becomes unclear: you can't tell whether the variable is empty because nobody set it yet, or because someone reset it on purpose. If you want to say “intentionally empty” in your own code, use null. That is what it is for.

Real Example — Traced Line By Line

undefined.js
console.log(hotelName);      // undefined — reserved, not yet assigned
console.log(typeof unknownX); // "undefined" — never declared, but typeof is safe
console.log(unknownX);       // ReferenceError: unknownX is not defined

var hotelName = "Grand Palace";
console.log(hotelName);      // "Grand Palace"
step 1 / 7
Memory creation phase
Memory phase

hotelName → undefined reserved, because of the var on line 5. unknownX is never declared anywhere, so nothing is reserved for it at all — there is no slot with that name.

undefined.js
1console.log(hotelName); // undefined
2console.log(typeof unknownX); // "undefined"
3console.log(unknownX); // ReferenceError
4
5var hotelName = "Grand Palace";
6console.log(hotelName); // "Grand Palace"
Global EC · memory
hotelNameundefined
unknownXno slot
Console
(nothing yet)
Step through the file. Watch the lookup land on a real-but-empty slot, on no slot at all (safely, via typeof), and on no slot at all directly — which crashes. · interactive
  1. Memory phase

    hotelName → undefined reserved. unknownX is never declared anywhere, so nothing is reserved for it at all.

  2. console.log(hotelName)

    Prints undefined — the reserved slot exists, just empty so far.

  3. console.log(typeof unknownX)

    Prints "undefined" — safe, because typeof does not throw on a name that was never declared.

  4. console.log(unknownX)

    Throws ReferenceError: unknownX is not defined — direct access has no such safety net.

  5. hotelName is assigned

    Now printing it gives the real value, "Grand Palace".

See It Live — Console & DevTools

  1. Open the console

    Any page → DevTools (the debugging tools built into the browser, opened with F12) → Console tab.

  2. Declare without assigning

    console
    var guestName;
    console.log(guestName); // undefined
  3. Reference something never declared

    console
    console.log(neverDeclared); // ReferenceError, in red
  4. Compare with typeof

    console
    console.log(typeof neverDeclared); // "undefined" — no error this time
  5. Set a breakpoint before any declarations run

    Open the Scope panel. You'll see guestName already listed under Global with the value undefined, even before its line has run. This shows the memory creation phase from Lesson 1.

Common Misconceptions

“undefined and not defined are just two ways of saying the same thing.” They're not — undefined is a real value for a variable that exists but is empty; “not defined” is a ReferenceError for a name that was never declared at all.

“undefined and null are interchangeable.” Both represent “nothing,” but undefined is the engine's default for not-yet-assigned, while null is a value you assign deliberately to mean “intentionally empty.”

“Checking a variable directly is just as safe as using typeof.” Only if you are sure it was declared somewhere. For anything that might not exist at all, such as an optional global or a variable from another script, typeof is the safe way to check.

Interview Questions

What is the real difference between undefined and “not defined”?

undefined means memory was reserved for the variable but no value assigned yet. “Not defined” means the name was never declared anywhere, so no memory exists for it at all — referencing it throws a ReferenceError.

Why doesn't typeof throw an error on an undeclared variable?

typeof is built to be a safe existence check. It returns the string "undefined" for both a declared variable with no value and a never-declared name, instead of throwing. (It does still throw for a let/const in the Temporal Dead Zone.)

What's the practical difference between null and undefined?

undefined is set automatically by the engine to mean “not yet assigned.” null is set deliberately by the programmer to mean “intentionally empty.”

Is undefined truthy or falsy?

Falsy, which means it counts as false in a condition. The other falsy values are null, 0 (and -0), 0n, "", false, and NaN.

Why is JavaScript called a loosely typed language?

Because a variable's type isn't fixed when you declare it. The same variable can hold a number, then a string, then a boolean, because the type belongs to the value the variable holds right now. (Strictly, this is called dynamic typing.)

Is it good practice to manually assign undefined to a variable?

No — it blurs the engine's own signal for “not yet assigned.” If you want to represent “intentionally empty” in your own code, assign null instead.

Published by Jainik · Last updated · How these lessons are made

Keep learning

Related series