Shivam Katare

Understanding Undefined Versus Not Defined in JavaScript

9 min read

Cover Image for Understanding Undefined Versus Not Defined in JavaScript

JavaScript is a great language, but it's quite different from other languages. It has many unique features that don't work the same way as in other languages. One distinctive aspect is the concept of undefined, which sets it apart from other languages. It's important to note that undefined is not the same as not defined. These two are different and carry different meanings.

These two terms may not confuse you if you are a professional or have a good amount of experience with JavaScript. However, as a beginner, it can be confusing at times. Therefore, in this blog, we will discuss these two terms to understand them better. So, without further delay, let's get started.

undefined in JavaScript

To get to know about undefined, you should first know how JavaScript executes code. If you'll be clear on that part, it will be easy for you to understand these terms. So, let's go with that flow first.

JavaScript code executes differently. It creates a global execution context and allocates the memory to all the variables and functions even before a single line of code is executed.

In simple terms, the global execution context in JavaScript is like the stage where all the action happens. Before any code runs, JavaScript sets up this stage by creating a space in memory for all the variables and functions that will be used throughout the program. It's like preparing the workspace before starting any tasks โ€“ everything is ready and waiting for the code to begin executing.

So, if you declare a variable let's say num

let num = 27;

In JavaScript, when you declare a variable num, and assign a value to it, like 27, JavaScript pre-allocates memory for it. This happens before any code execution takes place. So, even though the value is not yet executed or known, JavaScript still reserves memory space for it. This reserved space is marked as undefined, like a placeholder until the actual value is assigned during execution.

So, in memory before execution, this num variable will contain undefined.

Javascript Execution Context | Call stack

So, in the above image, we have variables a, b, and sum. Before the code execution, JavaScript places these variables in memory and uses undefined as a placeholder for all three variables. This is because the code has not been executed yet, so JavaScript doesn't know what values they will hold. It fills these positions with the keyword undefined. When we obtain those values, you can see that the undefined placeholders are completely replaced by the actual values, and we get our results.

Cases of undefined

You'll see undefined in many situations. Let's explore some common scenarios:

  1. Variable Declaration without Initialization:

    When a variable is declared but not initialized with a value, it holds the value undefined by default. JavaScript recognizes that the variable is declared and can have a value assigned to it. Therefore, it automatically assigns undefined to it as a placeholder until an actual value is assigned.

     let x;
     console.log(x); // Output: undefined
    
  2. Accessing an Index that Doesn't Exist in an Array:

    When attempting to access an index in an array that hasn't been assigned a value, JavaScript returns undefined. But, in this case, this undefined will not take up any space.

     let arr = [1, 2, 3];
     console.log(arr[5]); // Output: undefined
    

    So, in the case of arr[5], where arr is [1, 2, 3], there is no space allocated for index[5] because the array only contains elements at 0, 1, and 2. When you access arr[5], JavaScript doesn't allocate memory for it; instead, it returns undefined because there is no value assigned to that index in the array. Therefore, undefined itself doesn't occupy space in memory in this context; it's more of a placeholder indicating the absence of a value at that specific index.

  3. Function Returns No Value:

    If a function doesn't explicitly return a value, JavaScript implicitly returns undefined.

     function greet() {
         // No return statement
     }
    
     console.log(greet()); // Output: undefined
    

    The greet() function does not have a return statement. Therefore, when you call greet(), it does not return any value explicitly, and JavaScript implicitly returns undefined. So, the output of console.log(greet()) will be undefined.

In this case, undefined represents the absence of a return value from the function. It doesn't take up space in memory like other data types, but it serves as a signal that the function didn't produce a specific result.

  1. Accessing Non-Existent Object Property:

    When trying to access a property of an object that doesn't exist, JavaScript returns undefined.

     let obj = { name: "John", age: 30 };
     console.log(obj.address); // Output: undefined
    
  2. Using undefined Keyword:

    Not a good practice. You can directly assign undefined to a variable or use it as a value.

     let y = undefined;
     console.log(y); // Output: undefined
    
  3. Implicitly Assigned to Unassigned Variables:

    Variables that are declared but not initialized automatically hold the value undefined.

     let z;
     console.log(z); // Output: undefined
    

These are some common scenarios where undefined is encountered in JavaScript code.

undefined taking space or not?

In JavaScript, undefined itself is a primitive value and it does not occupy any space in memory when it is used to represent the absence of a value or the result of an operation.

However, in certain cases, when a variable is declared but not initialized with a value, or when an index in an array is accessed but no value is assigned to it, JavaScript assigns the value undefined to represent the absence of a value. In these cases, memory is allocated for the variable or the array, and undefined is used as a placeholder to indicate that no actual value has been assigned.

let a;

// output will be undefined

// 1. Memory is allocated for the variable a.
// 2. The value of a is undefined until it is explicitly assigned another
//    value.
// 3. The value undefined itself does not take up additional memory space
//    beyond what is already allocated for the variable a.

So, while undefined itself doesn't take up space in memory, it is used as a placeholder to represent the absence of a value in certain contexts where memory has been allocated.

undefined != empty

undefined != empty: The value undefined is not the same as an "empty" value. In JavaScript, undefined represents the absence of a value or the uninitialized state of a variable, whereas "empty" typically refers to a value that exists but contains no data.

For example:

let x;
console.log(x); // Output: undefined

let y = '';
console.log(y); // Output: (empty string)

In the first example, x is declared but not assigned a value, so its value is undefined. In the second example, y is assigned an empty string '', which means it contains no characters but still exists as a string variable.

So, undefined and "empty" are different concepts in JavaScript, and they are not equivalent.

not defined in JavaScript

In JavaScript, "not defined" refers to a situation where you attempt to access a variable or function that has not been declared or defined anywhere in the code. This results in a reference error because the JavaScript engine cannot find any reference to the variable or function you're trying to use.

console.log(name); // Output: Uncaught ReferenceError: name is not defined

In this example, we're trying to access a variable name that has not been declared or assigned anywhere in the code. As a result, JavaScript throws a ReferenceError stating that name is not defined.

Similarly, if you try to access a function that hasn't been defined, you'll see the same type of error:

printName(); // Output: Uncaught ReferenceError: printName is not defined

Here, printName is not defined as a function anywhere in the code, so attempting to call it results in a ReferenceError.

So, not defined in JavaScript indicates a situation where the interpreter cannot find a reference to the variable or function you're attempting to use, leading to a ReferenceError. This often occurs when there's a typo in the variable or function name, or when you're trying to access a variable or function that hasn't been declared in the current scope.

Best Practices

There might be errors due to undefined and not defined, so it's good to handle these errors in the code. Let's learn how to manage situations when errors like this occur and explore a best practice to follow. Here are some useful tips and best practices for handling these situations:

  1. Always Declare Variables:

    Ensure that you declare variables before using them to avoid not defined errors. Use let, const, or var to declare variables explicitly.

     let x; // Declare variable x
     console.log(x); // Output: undefined
    
  2. Check for Undefined Values:

    Before using variables or accessing object properties, check if they are undefined to prevent runtime errors.

     let obj = {};
     if (typeof obj.property !== 'undefined') {
         // Access obj.property only if it's defined
     }
    
  3. Default Values with Fallback Operator (??):

    Use the fallback operator (??) to provide default values for variables that might be undefined.

     let x;
     let y = x ?? 'default'; // Set y to 'default' if x is undefined
    
  4. Use Optional Chaining (?.) for Object Properties:

    Use optional chaining (?.) when accessing nested object properties to handle undefined values.

     let obj = { prop: { nestedProp: 'value' } };
     let value = obj.prop?.nestedProp; // Safe access to nested property
    
  5. Avoid Global Variables:

    Minimize the use of global variables to reduce the risk of variable collisions and not defined errors.

  6. Use Linters:

    You can use linting tools like ESLint to identify and fix potential issues related to undefined and not defined variables.

  7. Consistent Error Handling:

    Handle errors consistently across your codebase. Use try-catch blocks or error callbacks to handle unexpected errors and prevent script termination.

  8. Unit Testing:

    Write unit tests to cover different scenarios, including cases involving undefined and not defined values, to ensure code reliability and maintainability.

By following these best practices and tips, you can effectively manage undefined and not defined values in your JavaScript code, making your applications stronger and more resistant to errors.

Conclusion

So, yeah, that's it for this blog. In this blog, we discussed the concepts of undefined and not defined in JavaScript, covering their differences, common scenarios when they occur, best practices for handling errors related to them, and tips for improving code reliability.

Thanks for reading this blog. If you learned something from it, please like and share it with your friends and community. I write blogs and share content on JavaScript, TypeScript, Open Source, and other web development-related topics. Feel free to follow me on my socials. I'll see you in the next one. Thank You :)

TV gif. Gabriel Chavarria as Jacob in East Los High. He walks in front of the school and waves hello to us eagerly.