Difference between undefined and not defined

Hello friends, welcome to shrash studio learning, in this article we are going to explore one of the most unique and often misunderstood concepts in JavaScript — the undefined keyword. We will deeply understand what undefined actually means, why it exists, how it relates to JavaScript's internal execution model, how it is different from "not defined," and why JavaScript is considered a loosely typed language. We will also look at practical code examples, step-by-step execution breakdowns, common mistakes developers make with undefined, and real-world usage scenarios. By the end of this article, you will have a complete and crystal-clear understanding of undefined in JavaScript.

What is undefined in JavaScript

The undefined keyword in JavaScript is something truly unique to this language. Unlike many other programming languages such as C, C++, or Java, JavaScript has a built-in special value called undefined that plays a crucial role in the way programs are executed. It is not simply an error or an empty value — it carries a very specific meaning tied to JavaScript's core execution mechanism.

In simple terms, undefined is a primitive data type and a keyword that JavaScript automatically assigns to a variable at the moment memory is allocated for it, but before any actual value has been placed into that variable. It acts as a default placeholder indicating that the variable exists in memory but has not yet been given a meaningful value by the programmer.

This behavior is deeply connected to how JavaScript creates its execution context. Before even a single line of your code runs, JavaScript scans through the entire script, identifies all variable declarations and function definitions, and allocates memory for them. During this phase, all variables receive the value undefined as a placeholder. This entire process is known as the memory creation phase, and undefined is the heart of it.


var a = 7;

console.log(a); // Output: 7

In the example above, even before the assignment a = 7 is executed, JavaScript has already allocated memory for a and stored the value undefined in it. The value 7 is only placed into a once that specific line actually runs during the code execution phase.

Why undefined Exists in JavaScript

Understanding why undefined was introduced into JavaScript requires understanding how JavaScript's execution engine works at a fundamental level. Unlike languages that wait to allocate memory at the exact point where a variable is declared in code, JavaScript follows a two-phase execution model. This design choice was made to give JavaScript its unique hoisting behavior and flexible runtime nature.

During the first phase — the memory creation phase — the JavaScript engine scans the entire script and reserves memory for every variable and function it finds. At this point, it does not know what value the programmer intends to assign to these variables, so it must use something as a default filler. That filler is undefined. Without this placeholder, trying to access a variable before its assignment line would cause unpredictable behavior or crashes.

So undefined exists precisely because JavaScript wants to be forgiving and predictable. Instead of throwing an error every time you reference a variable that has been declared but not yet assigned, it gives you a consistent, checkable value. This allows developers to write conditional logic based on whether a variable has been initialized or not.


console.log(a); // Output: undefined

var a = 7;

console.log(a); // Output: 7

In the example above, the first console.log(a) runs before the assignment line. Since JavaScript already allocated memory to a during the memory creation phase and stored undefined in it, the output is undefined rather than an error. After the assignment executes, the second log correctly outputs 7.

Internal Working: How JavaScript Allocates Memory

To truly appreciate undefined, you need to understand the internal mechanics of JavaScript's execution context. Whenever a JavaScript program starts running, the engine creates a Global Execution Context. This context has two distinct phases that happen in sequence: the memory creation phase and the code execution phase.

During the memory creation phase, the engine goes through the code line by line, not to execute it, but to identify declarations. Every variable declaration it encounters gets a slot in memory with undefined stored as the default value. Every function declaration gets the entire function body stored in memory. This entire memory phase completes before even the first actual line of code runs.

Once the memory phase finishes, the engine moves into the code execution phase. Now it starts running the code top to bottom. When it reaches an assignment statement, it replaces the undefined placeholder with the actual assigned value. This two-phase model is the fundamental reason hoisting works in JavaScript and why undefined is so central to the language.


// MEMORY CREATION PHASE (before code runs):
// a --> undefined  (placeholder stored in memory)

// CODE EXECUTION PHASE (code runs line by line):
var a = 7;   // now 'a' is updated from undefined to 7

console.log(a); // Output: 7

The comment annotations in the example above illustrate what the JavaScript engine does behind the scenes. Notice that the memory for a is created before any visible code executes, and only during the execution phase is the placeholder replaced with the real value.

Practical Examples of undefined in Action

Let us look at a variety of practical code scenarios that demonstrate how undefined behaves in different situations. These examples will help solidify your understanding and prepare you for real-world JavaScript development.

Example 1: Accessing a Variable Before Assignment


console.log(a); // Output: undefined

var a = 5;

console.log(a); // Output: 5

In this example, when the first console.log(a) is encountered, the variable a has already been placed in memory by the JavaScript engine during the memory creation phase, but no value has been assigned yet. As a result, its value is undefined. After the assignment a = 5, the second log correctly prints 5.

Example 2: Checking Whether a Variable is undefined


var a;

if (a === undefined) {
    console.log("a is undefined");
} else {
    console.log("a is not undefined");
}

// Output: a is undefined

Here, the variable a is declared but never assigned any value. Throughout the entire program, it holds the placeholder undefined. The strict equality check a === undefined returns true, so the first message is printed. Once you assign a value such as a = 10, the condition becomes false and the second message would print instead.

Example 3: Variable Changing Types Over Time


var a;

console.log(a);        // Output: undefined

a = 10;
console.log(a);        // Output: 10

a = "Hello World";
console.log(a);        // Output: Hello World

This example beautifully demonstrates both undefined and JavaScript's loosely typed nature. The variable a starts as undefined, then becomes a number, and then becomes a string. JavaScript allows this seamlessly because it does not lock a variable to a specific data type. This flexibility is a defining characteristic of loosely typed languages.

Output Breakdown

Understanding what output to expect from code involving undefined is essential for debugging and writing clean JavaScript. Let us examine what the engine actually produces at each stage of execution in a comprehensive example.


var a;

console.log(a);    // Output: undefined

a = 10;
console.log(a);    // Output: 10

a = "Hello";
console.log(a);    // Output: Hello

a = true;
console.log(a);    // Output: true

The outputs follow a clear pattern. The first log produces undefined because no assignment has occurred. Each subsequent log reflects the current value stored in a. The important takeaway is that undefined is the starting state and can be replaced by any data type at any point during the program's execution.

Step-by-Step Execution of a JavaScript Program with undefined

To fully internalize how undefined fits into the JavaScript execution model, let us walk through a complete program step by step and track exactly what happens at each stage.


console.log(a);    // Step 3

var a = 7;         // Step 4

console.log(a);    // Step 5

Step 1 — Global Execution Context Created: JavaScript begins by creating a Global Execution Context. This context manages everything that happens during the program run.

Step 2 — Memory Creation Phase: The engine scans all declarations. It finds var a and reserves memory for it. Since no value has been assigned yet, it stores undefined as a placeholder in that memory slot.

Step 3 — Code Execution Begins, First Log Runs: The first console.log(a) executes. The engine looks up a in memory and finds undefined. It prints undefined to the console.

Step 4 — Assignment Executes: The line var a = 7 runs. The engine updates the memory slot for a, replacing undefined with 7.

Step 5 — Second Log Runs: The second console.log(a) executes. The engine looks up a and now finds 7. It prints 7 to the console.

undefined vs Not Defined: A Critical Distinction

One of the most important distinctions in JavaScript that beginners frequently confuse is the difference between undefined and "not defined." These two things sound similar but represent entirely different situations and produce very different results when encountered in code.

undefined means that a variable has been declared and memory has been allocated for it, but no value has been assigned to it yet. The variable exists in memory — it just holds the default placeholder value. When you access it, JavaScript finds it and returns undefined.

"Not defined," on the other hand, means that no memory was ever allocated for that identifier. The variable was never declared in the code, so the JavaScript engine has no record of it at all. When you try to access a variable that was never declared, JavaScript throws a ReferenceError, indicating that the identifier cannot be found anywhere in memory.


var a = 7;

console.log(a);    // Output: 7      (declared and assigned)

var b;
console.log(b);    // Output: undefined  (declared but not assigned)

console.log(x);    // Output: ReferenceError: x is not defined
                   // (never declared — no memory allocated)

In this example, a has been declared and assigned, so it prints normally. b has been declared but not assigned, so it prints undefined. The variable x was never declared, so JavaScript throws a ReferenceError. This is the critical difference: undefined confirms existence in memory; "not defined" signals complete absence.

Aspect undefined Not Defined (ReferenceError)
Memory Allocated Yes No
Variable Declared Yes No
Value undefined (placeholder) Does not exist
Accessing the Variable Returns undefined Throws ReferenceError
Caused by Declaration without assignment No declaration at all

Common Mistakes Developers Make with undefined

Now that you understand what undefined is, let us look at the mistakes that even experienced developers occasionally make when working with it. Avoiding these pitfalls will make your code more predictable, maintainable, and professional.

Mistake 1: Manually Assigning undefined to a Variable

Perhaps the most important mistake to avoid is deliberately assigning undefined as a value to a variable. While JavaScript technically allows this — since undefined is a valid value — it is considered a very bad practice. The entire purpose of undefined is to serve as a natural, automatic signal that a variable has not been assigned a meaningful value yet. When you manually assign it, you are overriding that signal and creating confusion.


// BAD PRACTICE - Do not do this
var a = undefined;

console.log(a);    // Output: undefined
// This creates ambiguity — was 'a' ever assigned intentionally?

Important: If you want to intentionally represent the absence of a meaningful value, use null instead of undefined. That is the conventional, semantically correct way to express intentional emptiness in JavaScript.

Mistake 2: Confusing undefined with Empty or Null

Many beginners assume that undefined means the variable is empty or takes up no memory. This is completely incorrect. undefined is itself a concrete value with its own memory footprint. It is a data type and a keyword. The difference between undefined, null, and an empty string are all meaningful distinctions in JavaScript, and treating them as the same will lead to bugs.


var a;             // undefined — declared, not assigned
var b = null;      // null — intentionally assigned as empty
var c = "";        // empty string — assigned an empty string value

console.log(a);    // Output: undefined
console.log(b);    // Output: null
console.log(c);    // Output: (empty string)

console.log(a === b);    // Output: false (different types)
console.log(a === c);    // Output: false (different types)

This comparison illustrates that undefined, null, and an empty string are three completely different things in JavaScript. Mixing them up is a common source of hard-to-track bugs in real-world applications.

Mistake 3: Not Checking for undefined Before Accessing Properties

If you try to access a property on a variable that is undefined, JavaScript will throw a TypeError. Always verify that a variable holds a valid value before attempting to use it as an object or call its methods.


var user;

// WRONG - Will throw TypeError: Cannot read properties of undefined
// console.log(user.name);

// CORRECT - Check first
if (user !== undefined) {
    console.log(user.name);
} else {
    console.log("User has not been initialized yet");
}

// Output: User has not been initialized yet

Comparison: undefined in JavaScript vs Other Languages

One of the things that makes JavaScript stand out from languages like C, C++, Java, or Python is the existence of undefined as a language-level concept. In most strongly typed or statically typed languages, you cannot access a variable before it has been given a value — the compiler or runtime would refuse to proceed. JavaScript takes a different, more permissive approach.

Feature JavaScript C / C++ Java Python
Unassigned Variable Default undefined Garbage value / Compiler Error Compiler Error NameError (no declaration)
Access Before Assignment Returns undefined Undefined behavior / Error Compile-time error Runtime NameError
Dynamic Typing Yes (loosely typed) No (strictly typed) No (strictly typed) Yes (dynamically typed)
Memory Pre-allocation Yes (hoisting phase) No (at declaration point) No (at declaration point) No (at assignment point)

This comparison shows that JavaScript's approach to undefined is intentional and unique. It reflects JavaScript's design philosophy of being a flexible, forgiving language that prioritizes runtime adaptability over compile-time strictness.

JavaScript as a Loosely Typed Language

The concept of undefined is also deeply connected to one of JavaScript's most defining characteristics: it is a loosely typed — sometimes called weakly typed — language. In a strictly typed language like C or Java, once you declare a variable as an integer, it can only hold integer values. Assigning a string to it would result in a compile-time error.

JavaScript works very differently. A single variable can hold any type of value at any point in time. It can start as undefined, become a number, transform into a string, and then store a boolean — all in the same program without any errors. The JavaScript engine handles all type management internally and dynamically.


var a;
console.log(typeof a);    // Output: "undefined"

a = 42;
console.log(typeof a);    // Output: "number"

a = "JavaScript";
console.log(typeof a);    // Output: "string"

a = true;
console.log(typeof a);    // Output: "boolean"

a = { name: "Rahul" };
console.log(typeof a);    // Output: "object"

The typeof operator helps you inspect what type a variable currently holds at any point in execution. As shown above, JavaScript freely allows the same variable to transition through multiple data types during the lifetime of a program. This is what makes JavaScript loosely typed — the variable is not locked to a single data type at declaration time.

Note: The terms "loosely typed" and "weakly typed" are often used interchangeably in the JavaScript community. Neither term implies that the language is inferior. In fact, this flexibility allows JavaScript to manage a great deal of complexity behind the scenes, making it one of the most powerful languages for building dynamic, responsive applications.

Real-World Usage of undefined

Understanding undefined is not just an academic exercise — it has direct, practical implications in everyday JavaScript development. Developers frequently encounter and work with undefined in real-world codebases across various scenarios.

Scenario 1: Optional Function Parameters

When a function is called without providing all its expected arguments, the missing parameters automatically receive the value undefined. This behavior can be used to write functions that behave differently depending on whether an argument was provided.


function greetUser(name) {
    if (name === undefined) {
        console.log("Hello, Guest!");
    } else {
        console.log("Hello, " + name + "!");
    }
}

greetUser("Rahul");    // Output: Hello, Rahul!
greetUser();           // Output: Hello, Guest!

In this real-world pattern, the function gracefully handles the case where no name is supplied by checking for undefined and falling back to a default greeting. This is a very common pattern in JavaScript libraries and APIs.

Scenario 2: Checking Object Properties

When you access an object property that does not exist, JavaScript returns undefined rather than throwing an error. This is useful for safely checking whether an object contains a certain field before attempting to use it.


var user = {
    name: "Priya",
    age: 25
};

console.log(user.name);      // Output: Priya
console.log(user.age);       // Output: 25
console.log(user.email);     // Output: undefined (property doesn't exist)

if (user.email === undefined) {
    console.log("Email not provided");
}

// Output: Email not provided

Accessing user.email returns undefined because the email property was never defined on the object. The conditional check allows the program to handle this gracefully instead of crashing or producing unexpected behavior.

Scenario 3: Array Elements

When you access an index position in an array that does not contain a value, JavaScript returns undefined for that position as well.


var fruits = ["apple", "banana", "mango"];

console.log(fruits[0]);    // Output: apple
console.log(fruits[1]);    // Output: banana
console.log(fruits[5]);    // Output: undefined (index out of range)

The index 5 does not exist in the array, so JavaScript returns undefined. This is another practical scenario where understanding undefined prevents confusion about why a value is not appearing as expected.

Summary

undefined is one of the most foundational and unique aspects of JavaScript. Unlike other programming languages, JavaScript uses undefined as a default placeholder value that is automatically assigned to all declared variables during the memory creation phase of execution — before a single line of code runs. This behavior is a direct result of JavaScript's two-phase execution model involving the Global Execution Context.

The key difference between undefined and "not defined" is clear: undefined means the variable exists in memory but has not been assigned a value, while "not defined" means the variable was never declared and no memory exists for it at all. Accessing an undefined variable returns the value undefined, while accessing a completely undeclared variable causes a ReferenceError.

JavaScript's loosely typed nature means that a single variable can hold any data type at any time — starting from undefined and freely transitioning between numbers, strings, booleans, and objects. This flexibility is a feature, not a weakness, and allows JavaScript to handle complex dynamic scenarios elegantly.

The most important best practice to remember is to never manually assign undefined to a variable. Let JavaScript use it for its intended purpose — as an automatic signal that a variable has not yet been given a meaningful value. If you need to represent intentional emptiness, use null instead. Respecting the semantic purpose of undefined will make your code cleaner, more consistent, and easier for other developers to understand and maintain.

Concept Key Takeaway
undefined Auto-assigned placeholder during memory creation phase
Not Defined Variable was never declared — causes ReferenceError
Loosely Typed Variables can hold any data type at any time
Manual Assignment Avoid assigning undefined manually — use null instead
Memory Phase All declarations get undefined before code runs
Real-World Use Optional params, missing properties, uninitialized variables

Chakrapani U

Hi, I’m Chakrapani Upadhyaya, an IT professional with 15+ years of industry experience. Over the years, I have worked on web development, enterprise applications, database systems, and cloud-based solutions. Through this blog, I aim to simplify complex technical concepts and help learners grow from beginners to confident, industry-ready developers.

Previous Post Next Post

نموذج الاتصال