cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

undefined

Learn where JavaScript creates undefined, how to tell it from missing names, and how defaults, JSON, void, and safe checks behave.

By the end, you can
  • 01
    Recognize every common sourcePredict when variables, properties, indexes, arguments, returns, Maps, and searches produce undefined.
  • 02
    Separate absence from errorsExplain the difference between a declared value that is undefined, a missing property, and a name that is not defined.
  • 03
    Use safe defaultsChoose === undefined, typeof, ??, ?., parameter defaults, destructuring defaults, and JSON behavior on purpose.

undefined in one sentence

undefined is JavaScript's value for “nothing has been put here yet.” It is both a value and its own primitive type: typeof undefined returns the string "undefined".

Definition

undefined means a variable, property, argument, return value, or lookup has no supplied value. It is a real value, not the same thing as a name that was never declared.

The smallest undefined examplesPop out in the code editor (opens in a new tab)JavaScript
let formField;var oldStyle;console.log(undefined);console.log(typeof undefined);console.log(formField);console.log(oldStyle);

Lines 1 and 2 create declared bindings. Because neither has an initializer yet, lines 5 and 6 print undefined. Line 4 is different: it prints the type string, which happens to have the same letters.

A const declaration must have a valuePop out in the code editor (opens in a new tab)JavaScript
const needsValue;

let and old-style var can be uninitialized. const cannot. The hoisting lesson explains why var declarations also appear as undefined before assignment in classic scripts.

Real-life analogyAn empty labelled locker

Imagine a row of lockers. One locker has your label but is empty: that is like a declared variable whose value is undefined. A locker number that does not exist is different: asking for it is closer to a ReferenceError.

In real life: The locker exists and has your label
In JavaScript: A declared variable or property name exists
In real life: Nobody has put a bag inside yet
In JavaScript: The value is undefined
In real life: A locker number that is not on the wall
In JavaScript: A name that is not defined at all

Where the analogy stops: A real empty locker is visible. JavaScript's undefined is a value used in several situations, and some missing paths throw errors instead.

Where JavaScript creates it

STEP THROUGH

Most undefined values are not mistakes. They are JavaScript's normal answer when a value was not assigned, found, passed, or returned. Step through these origins one by one.

Trace common origins of undefined
Step 0 of 16Ready
Your turn: follow the blue line

Walk through many ordinary origins of undefined: unfilled variables, absent object keys, sparse arrays, strings, Maps, empty arrays, and failed searches.

Running in
  1. script
Next: line 1
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
let oldCounter;const profile = { name: "Ada" };const tasks = ["learn"];const sparse = [1, , 3];const pantry = new Map([["tea", 2]]); console.log(draftTitle);console.log(oldCounter);console.log(profile.age);console.log(tasks[5]);console.log(sparse[1]);console.log("abc"[5]);console.log(tasks.at(-10));console.log(pantry.get("coffee"));console.log([].pop());console.log([1, 2].find((n) => n > 5));
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

The replay includes uninitialized let and var, missing object properties, out-of-range indexes, an array hole, "abc"[5], arr.at(-10), Map#get for a missing key, [].pop(), and find with no match.

Missing properties, indexes, and holes

Reading a missing property is safe when the object itself exists. Reading through a missing middle value is not safe. A sparse array hole also reads as undefined, but it is not the same as a stored value.

Absent slots return undefinedPop out in the code editor (opens in a new tab)JavaScript
const user = { name: "Ada" };const scores = [10, 20];const sparse = [1, , 3]; console.log(user.age);console.log(scores[5]);console.log(sparse[1]);console.log(1 in sparse);console.log("abc"[5]);console.log(scores.at(-10));

The 1 in sparse line prints false, proving index 1 is a hole rather than a present element. The read still gives undefined.

A missing middle value throwsPop out in the code editor (opens in a new tab)JavaScript
const user = {};console.log(user.address.city);

Use optional chaining, such as user?.address?.city, when each step might be missing and the safe result should be undefined instead of a TypeError.

Arguments and return values

STEP THROUGH

Function parameters are local variables. If a call supplies fewer arguments than the function names, the extra parameters start as undefined. A function with no returned value also produces undefined.

Call a function with fewer arguments
Step 0 of 16Ready
Your turn: follow the blue line

Call the same function with all arguments, fewer arguments, explicit undefined, and null. Watch when the default parameter runs.

Running in
  1. script
Next: line 5
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
function greet(name = "friend", punctuation = "!") {  return "Hello, " + name + punctuation;} console.log(greet());console.log(greet(undefined, "?"));console.log(greet(null));
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Defaults run only when the argument is missing or explicitly undefined. Passing null is different: it is a value, so the default does not run. The later comparison lesson Booleans, null & undefined puts that side by side with null.

Return values that are undefinedPop out in the code editor (opens in a new tab)JavaScript
function showArgument(value) {  console.log(value);}function noReturn() {  const status = "saved";}function bareReturn() {  return;} showArgument();console.log(noReturn());console.log(bareReturn());const printed = console.log("console.log prints first");console.log(printed);console.log([1, 2].forEach((n) => n * 2));console.log([1, 2].find((n) => n > 5));console.log(new Map().get("missing"));console.log([].pop());

Line 14 proves a subtle point: console.log prints its message and then returns undefined. forEach is similar: it runs a callback for side effects and returns undefined.

undefined vs not defined

undefined means a binding exists and currently holds the undefined value. Not defined means JavaScript cannot find a binding for the name at all.

Declared, empty, and undeclared with typeofPop out in the code editor (opens in a new tab)JavaScript
let declared;console.log(declared);console.log(typeof declared);console.log(typeof neverDeclared);

The special typeof neverDeclared form returns the string "undefined" without throwing. That makes it useful for guarded checks around globals that may not exist.

Reading an undeclared name throwsPop out in the code editor (opens in a new tab)JavaScript
console.log(neverDeclared);

Checking and defaults

For a declared value, value === undefined is the direct check. For a name that might not exist, use typeof name === "undefined". For fallbacks, prefer ?? and ?. when 0, false, or "" should stay valid.

Present with undefined is not missingPop out in the code editor (opens in a new tab)JavaScript
const present = { key: undefined };const missing = {}; console.log("key" in present);console.log("key" in missing);console.log(Object.hasOwn(present, "key"));console.log(Object.hasOwn(missing, "key"));console.log(Object.keys(present).join(","));console.log(JSON.stringify(present));

A key can be present while its value is undefined. "key" in obj, Object.hasOwn, and Object.keys answer whether the property exists; reading obj.key answers what value is stored there.

Defaults apply only for undefinedPop out in the code editor (opens in a new tab)JavaScript
function greet(name = "friend") {  console.log("Hello, " + name);}greet(undefined);greet(null); const [first = "fallback", second = "backup"] = [undefined, null];const { label = "Untitled", count = 0 } = { count: undefined };console.log(first);console.log(second);console.log(label);console.log(count);

Parameter defaults and destructuring defaults use the fallback for undefined. They do not replace null, because null is an explicit value.

void and the global value

The void operator evaluates an expression and always produces undefined. The global undefined property is read-only and non-configurable in modern JavaScript.

void and the global descriptorPop out in the code editor (opens in a new tab)JavaScript
const descriptor = Object.getOwnPropertyDescriptor(globalThis, "undefined");console.log(descriptor.writable);console.log(descriptor.configurable);console.log(void 0);console.log(void "hello");

Since ES5, globalThis.undefined is non-writable and non-configurable. Assigning to it in sloppy code does nothing; assigning in strict mode throws a TypeError.

Sloppy assignment does not replace the globalJavaScript
undefined = "changed";console.log(undefined);
Strict assignment throwsPop out in the code editor (opens in a new tab)JavaScript
"use strict";undefined = "changed";

A local scope can technically shadow the name undefined, but never do that in real code. It makes examples harder to read and fights a value JavaScript already gives you. The engine details live in undefined inside the engine.

Operations and JSON

undefined is falsy, but operations still have exact conversion rules. Arithmetic turns it into NaN. String contexts print the word undefined. JSON treats it differently depending on where it appears.

Conversions and serializationPop out in the code editor (opens in a new tab)JavaScript
console.log(undefined + 1);console.log(`value: ${undefined}`);console.log(String(undefined));console.log(Number(undefined));console.log(undefined == null);console.log(undefined === null);console.log(JSON.stringify({ a: undefined }));console.log(JSON.stringify([undefined]));console.log(JSON.stringify(undefined));

The last line is the surprise: JSON.stringify(undefined) returns the undefined value itself, not a string. In objects, undefined properties are omitted; in arrays, undefined entries become null to preserve the slot.

Try real expressions

PLAYGROUND

Pick a tiny program and compare the value, the type, and the console output. Some choices return undefined; one deliberately throws because a middle property is missing.

Playground: pick an expression
Selected expressionPop out in the code editor (opens in a new tab)JavaScript
let x;console.log(x);
Real resultundefined
Expressionlet x; x
Valueundefined
Console outputundefined

A declared variable without an initializer starts with the undefined value.

Try it yourself

let x; x produces undefined with typeof undefined. Console output: undefined. A declared variable without an initializer starts with the undefined value.

The selected program is a real JavaScript snippet. The lesson tests run every option with Node's VM so the displayed result cannot drift from the language.

Sort the outcomes

SORTER

Similar-looking expressions can produce undefined, null, an error, or a different value entirely. Sort the cards by what JavaScript actually does.

undefined, null, or an error?
  • ({}).x
  • null.x
  • neverDeclared
  • [].pop()
  • "abc"[5]
  • "abc".match(/z/)
  • JSON.parse("null")
  • typeof neverDeclared
  • new Map().get("k")
  • [1, 2].find((n) => n > 5)
  • (() => {})()
  • void "hi"
  • [1, , 3][1]
  • ({ a: null }).a
  • JSON.stringify(undefined)
  • ({})?.address?.city
Try it yourself
0 of 16 correct

Place each expression in the category for its actual result.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Practical patterns

Real projects meet undefined in options objects, optional function parameters, and API responses with missing fields. The safe pattern is to read carefully, default narrowly, and keep valid falsy values.

Options objects and API fieldsPop out in the code editor (opens in a new tab)JavaScript
function connect(options = {}) {  const retries = options.retries ?? 3;  return "retries: " + retries;} const apiUser = { profile: { name: "Ada" } };console.log(connect({ retries: 0 }));console.log(connect({}));console.log(apiUser.profile?.address?.city ?? "Unknown city");
  • Use options = so callers may omit the whole options object.
  • Use ?? so 0 stays a real setting.
  • Use ?. before optional API fields that may be missing.
  • When an API must say “deliberately empty,” expect null and link to the null lesson.

Common misconceptions

  • “undefined means the variable does not exist.” No. A declared variable can hold undefined; an undeclared name throws when read.
  • “A missing property and a missing middle object behave the same.” No. obj.missing is safe; obj.missing.x throws.
  • “Array holes store undefined.” A hole is absent. Reading it produces undefined, but index in array is false.
  • “Defaults replace null.” Defaults replace only undefined and missing arguments or properties.
  • “JSON has an undefined value.” JSON has null, but no undefined literal.
Four ways a value can be absent
SituationSetupReading and typeofPresence checksJSON result
Declared but no valuelet x;typeof x is "undefined"; reading x gives undefinedNo object key unless you store oneJSON.stringify({ x }) becomes {}
Missing propertyconst obj = {}; obj.xtypeof obj.x is "undefined"; reading it gives undefined"x" in obj is falseJSON.stringify(obj) is {}
Present with value undefined{ x: undefined }Reading obj.x gives undefined"x" in obj and Object.hasOwn(obj, "x") are trueJSON omits the property
Not declaredneverDeclaredtypeof neverDeclared is the string "undefined", but reading it throws ReferenceErrorIt is not a binding you can check with inYou cannot serialize a name that cannot be read

Practice exercises

6 EXERCISES
Exercise 1 · Warm-upPredict three origins

Predict the three console lines in order.

Starter codePop out in the code editor (opens in a new tab)JavaScript
let x;
const obj = {};
console.log(x);
console.log(obj.missing);
console.log([1][1]);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upDefault or null?

    Predict what the two calls print.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    function label(value = "fallback") {
      return value;
    }
    console.log(label(undefined));
    console.log(label(null));

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticePresent or missing?

      Predict the two presence checks.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      const settings = { theme: undefined };
      console.log("theme" in settings);
      console.log("mode" in settings);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeSafe API access

        What exact city text prints?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        const user = { profile: {} };
        const city = user.profile?.address?.city ?? "Unknown";
        console.log(city);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · PracticeSerialize undefined

          Predict the three JSON outputs.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          console.log(JSON.stringify({ a: undefined }));
          console.log(JSON.stringify([undefined]));
          console.log(JSON.stringify(undefined));

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeGuard an undeclared name

            Which operator makes this guard safe even though maybeName was never declared?

            Starter codePop out in the code editor (opens in a new tab)JavaScript
            if (typeof maybeName === "undefined") {
              console.log("safe");
            }

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              8 QUESTIONS
              undefined quiz · 8 questionsScore: first tries count
              1. Question 1 of 8What does typeof undefined return?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log(typeof undefined);

                Choose an answer to see the explanation.

              2. Question 2 of 8What does an uninitialized let print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                let draft;
                console.log(draft);

                Choose an answer to see the explanation.

              3. Question 3 of 8What happens here?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                const user = {};
                console.log(user.address.city);

                Choose an answer to see the explanation.

              4. Question 4 of 8Which expression is safe for a name that might not be declared?

                Choose an answer to see the explanation.

              5. Question 5 of 8Which calls use the default parameter?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                function greet(name = "friend") {
                  console.log(name);
                }
                greet(undefined);
                greet(null);

                Choose an answer to see the explanation.

              6. Question 6 of 8What does void "hi" produce?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log(void "hi");

                Choose an answer to see the explanation.

              7. Question 7 of 8What do these comparisons print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log(undefined == null);
                console.log(undefined === null);

                Choose an answer to see the explanation.

              8. Question 8 of 8How does JSON handle undefined?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                console.log(JSON.stringify({ a: undefined }));
                console.log(JSON.stringify([undefined]));
                console.log(JSON.stringify(undefined));

                Choose an answer to see the explanation.

              Key takeaways

              • undefined is both a primitive value and the result of typeof undefined.
              • It appears when values are declared but unfilled, looked up but absent, not passed, or not returned.
              • Reading an undeclared name is a ReferenceError; typeof neverDeclared is the safe exception.
              • Defaults and destructuring fallbacks run for undefined, not for null.
              • Use ?., ??, Object.hasOwn, and JSON rules deliberately instead of guessing from truthiness.

              Final definition: undefined is JavaScript's built-in value and type for a place that exists but has no supplied value.

              Up next: null, the value you put in code when “nothing here” is intentional.

              CompleteFrontend Clear concepts. Working examples.