What Happens If You Set the Value of undefined in JavaScript? Behind the Scenes Explained
In JavaScript, undefined is a primitive value that often perplexes developers. It represents the absence of a defined value—think uninitialized variables, missing function parameters, or properties that don’t exist on objects. But here’s a curious question: Can you reassign undefined to a different value? And if you try, what happens behind the scenes?
This blog dives into the behavior of undefined in JavaScript, exploring its mutability across different language versions, scopes, and environments. We’ll uncover historical quirks, modern safeguards, and best practices to avoid pitfalls. By the end, you’ll understand why messing with undefined is generally a bad idea—and how JavaScript protects itself (and you) from accidental misuse.
Table of Contents#
- What is
undefinedin JavaScript? - Can You Assign a Value to
undefined? - Historical Behavior:
undefinedas a Mutable Property (Pre-ES5) - Modern JavaScript:
undefinedas a Non-Writable Property (ES5+) - What Happens If You Try to Assign to
undefinedToday? - Why Would Someone Try to Override
undefined? - Best Practices: Avoiding
undefinedAssignment - Conclusion
- References
What is undefined in JavaScript?#
Before we explore reassigning undefined, let’s clarify what undefined is.
undefined is one of JavaScript’s six primitive data types (alongside string, number, boolean, null, and symbol). It denotes that a variable has been declared but not assigned a value, or that a property does not exist on an object.
Examples of undefined in Action:#
let unassignedVar;
console.log(unassignedVar); // undefined (declared but not assigned)
function noReturn() {}
console.log(noReturn()); // undefined (function with no return statement)
const obj = { a: 1 };
console.log(obj.b); // undefined (property "b" does not exist)Crucially, undefined is distinct from null: null is an intentional absence of value, while undefined is an unintentional absence (e.g., a forgotten assignment).
Can You Assign a Value to undefined?#
The short answer: It depends on the JavaScript version and scope.
In the early days of JavaScript (pre-2009, before ECMAScript 5), undefined was mutable in global scope, meaning you could reassign it. This led to widespread bugs, so modern JavaScript (ES5+) strictly limits this behavior.
Historical Behavior: undefined as a Mutable Property (Pre-ES5)#
Before ES5 (2009), undefined was a writable property of the global object (e.g., window in browsers). This meant you could overwrite it like any other variable:
Example: Mutable undefined in Pre-ES5 Environments (e.g., IE 8)#
// Hypothetical pre-ES5 browser (e.g., IE 8)
undefined = "I'm not undefined anymore!";
var x; // Declared but unassigned
console.log(x === undefined); // false (x is the primitive undefined, but `undefined` now holds a string!)
console.log(undefined); // "I'm not undefined anymore!"This was catastrophic. Code relying on x === undefined to check for unassigned variables would fail, as undefined now held a custom value. Libraries and applications broke, prompting the ECMAScript committee to fix this in ES5.
Modern JavaScript: undefined as a Non-Writable Property (ES5+)#
ES5 (2009) overhauled undefined to prevent such misuse. The specification now defines the global undefined as a non-writable, non-enumerable, and non-configurable property of the global object (globalThis in modern terms).
Key Attributes of Global undefined (ES5+):#
[[Writable]]: false: Cannot be reassigned.[[Enumerable]]: false: Does not appear infor...inloops.[[Configurable]]: false: Cannot be deleted or modified (e.g., viaObject.defineProperty).
This lock-in ensures undefined remains reliable across all modern JavaScript environments.
What Happens If You Try to Assign to undefined Today?#
In modern JavaScript, the behavior of assigning to undefined depends on two factors: scope (global vs. local) and strict mode.
Global Scope#
In the global scope, undefined refers to globalThis.undefined, which is protected by ES5’s rules.
Case 1: Strict Mode ("use strict")#
Strict mode enforces stricter error handling. Assigning to undefined throws a TypeError:
"use strict";
undefined = 42; // TypeError: Cannot assign to read only property 'undefined' of object '[object global]'Case 2: Non-Strict Mode#
In non-strict mode, the assignment is silently ignored (no error, but undefined remains unchanged):
undefined = 42; // No error...
console.log(undefined); // Still undefined (assignment ignored)Local Scope: Shadowing undefined#
While the global undefined is protected, you can accidentally "shadow" undefined in local scopes by declaring a variable named undefined. This creates a local variable that overrides the global undefined within that scope.
Example: Shadowing undefined in a Function#
function shadowUndefined() {
var undefined = "oops"; // Local variable named "undefined"
var x; // Unassigned variable (primitive undefined)
console.log(x === undefined); // false (x is undefined; local "undefined" is "oops")
console.log(x); // undefined (primitive value)
console.log(undefined); // "oops" (local variable)
}
shadowUndefined();Here, the local undefined variable shadows the global one, leading to misleading comparisons.
Example: Shadowing in Block Scope#
if (true) {
let undefined = 100; // Block-scoped "undefined"
console.log(undefined); // 100 (local variable)
}
console.log(undefined); // undefined (global, unchanged)Why Would Someone Try to Override undefined?#
Most attempts to reassign undefined stem from misunderstanding or accident:
1. Misconception: undefined is a Variable#
Developers new to JavaScript may assume undefined is a variable (like null), not a primitive value. They might try to "define" it, unaware it’s a global property.
2. Accidental Shadowing#
A typo or oversight (e.g., var undefined = ...) can create a local undefined variable, breaking checks for unassigned values.
3. Legacy Code#
Older codebases (pre-ES5) might include intentional overrides, but this is rare today and strongly discouraged.
Best Practices: Avoiding undefined Assignment#
To avoid issues with undefined, follow these guidelines:
1. Never Declare Variables Named undefined#
Treat undefined as a reserved name. Avoid var undefined, let undefined, or const undefined in any scope.
2. Use typeof for Undefined Checks#
Instead of comparing directly to undefined, use typeof x === "undefined". This works even if undefined is shadowed:
function safeCheck() {
var undefined = "shadowed";
var y;
console.log(y === undefined); // false (flawed check)
console.log(typeof y === "undefined"); // true (reliable check)
}
safeCheck();3. Use void 0 for Primitive undefined#
The void operator evaluates an expression and returns undefined, bypassing shadowed variables:
var undefined = "shadowed";
console.log(void 0 === undefined); // false (void 0 is primitive undefined; local "undefined" is "shadowed")
console.log(void 0); // undefined (always the primitive value)4. Enable Strict Mode#
Strict mode ("use strict") turns silent failures (like global undefined assignment) into errors, catching mistakes early.
Conclusion#
JavaScript’s undefined has evolved from a mutable quirk to a protected primitive value. While modern JS (ES5+) locks down the global undefined, local shadowing remains a hazard.
- Global scope: Assigning to
undefinedthrows an error in strict mode and is ignored in non-strict mode. - Local scope: Declaring a variable named
undefinedshadows the global value, breaking comparisons.
To stay safe:
- Avoid naming variables
undefined. - Use
typeof x === "undefined"orvoid 0for reliable checks. - Enable strict mode to catch accidental assignments.
By respecting undefined’s role as a primitive value, you’ll write more robust, maintainable code.
References#
- MDN Web Docs:
undefined - ECMAScript 5 Specification: Global Object
undefinedProperty - Kangax: ES5 Compatibility Table
- JavaScript: The Good Parts by Douglas Crockford (discusses historical
undefinedissues)