Undeclared Variables in Non-Strict JavaScript
In non-strict JavaScript, assigning a value to a variable that was
never declared with var, let, or
const automatically creates a new property on the global
object, turning it into an implicit global variable. This behavior
bypasses standard lexical scoping rules, leading to unintended
consequences such as global scope pollution, accidental data overwrites,
and memory leaks.
How Implicit Global Creation Works
When the JavaScript engine encounters an assignment expression, such
as x = 10;, it begins an identifier lookup by traversing
the scope chain. It checks the current local scope, any outer function
scopes, and finally the global scope.
If no prior declaration of the variable is found anywhere in the
chain, non-strict mode assumes the variable should exist globally. The
engine creates a new property with that identifier directly on the
global object (window in web browsers or
global in Node.js) and assigns the specified value to
it.
function setCoordinates() {
// 'latitude' is not declared with let, const, or var
latitude = 40.7128;
}
setCoordinates();
console.log(window.latitude); // 40.7128 (accessible globally)Differences Between Implicit and Declared Globals
While an undeclared assignment functions like a global variable, it
has distinct behavioral differences from a variable declared globally
with var:
- Deletability: Properties created via undeclared
assignments are configurable properties on the global object. This means
they can be removed using the
deleteoperator. Explicitly declared global variables (var x = 10;) create non-configurable properties that cannot be deleted. - Hoisting Behavior: Declared variables are hoisted
to the top of their scope during the compilation phase, meaning they
exist (initialized to
undefined) before code execution reaches them. Undeclared assignments are not hoisted; accessing the variable before the assignment line executes results in aReferenceError.
Risks of Relying on Undeclared Variables
Implicit global variables introduce several structural risks into a codebase:
- Name Collisions: When multiple functions assign values to the same undeclared variable name, they overwrite each other’s data, causing unpredictable application state and bugs that are difficult to trace.
- Memory Leaks: Because global properties persist for the entire lifecycle of the webpage or application environment, data stored in implicit globals cannot be automatically garbage-collected.
- Reduced Maintainability: Code readability suffers when variables lack a clear point of declaration, making it hard for developers to determine the intended scope and lifetime of a value.
Prevention with Strict Mode
To eliminate the silent creation of implicit globals, ECMAScript 5
introduced strict mode. Adding "use strict"; at the top of
a JavaScript file or inside a specific function alters the assignment
behavior.
In strict mode, assigning a value to an undeclared variable
immediately halts execution and throws a
ReferenceError: <variable> is not defined, ensuring
all variables are explicitly declared before use.