Scoping in JavaScript
Scoping defines where variables are accessible in JavaScript. Scope is established when the code is written (at declaration time), not during function execution. This includes global scope (accessible everywhere), function scope (limited to a function), and block scope (limited to {}
blocks with let
and const
).
Advanced Example with Nested Functions
let globalVar = "I am global";
function outerFunction(x) {
let outerVar = "I am outer";
function innerFunction(y) {
let innerVar = "I am inner";
function deepestFunction(z) {
let deepestVar = "I am deepest";
console.log(`${globalVar}, ${outerVar}, ${innerVar}, ${deepestVar}, ${x}, ${y}, ${z}`);
}
deepestFunction("Z value");
}
innerFunction("Y value");
console.log(outerVar); // Accessible here
// innerVar or deepestVar not accessible here
}
function anotherOuter(a) {
let anotherVar = "I am another";
outerFunction("X value");
console.log(anotherVar); // Accessible here
// outerVar, innerVar, deepestVar not accessible here
}
anotherOuter("A value");
-
Explanation:
-
globalVar
is in global scope, accessible everywhere. -
outerVar
is inouterFunction
’s scope, accessible within it and its nested functions. -
innerVar
is ininnerFunction
’s scope, accessible to it anddeepestFunction
. -
deepestVar
is limited todeepestFunction
. - Parameters
x
,y
,z
, anda
are scoped to their respective functions. - Scope is set at declaration, so
outerVar
is unavailable outsideouterFunction
, even after execution.
-
What is a Closure?
A closure occurs when a function retains access to its outer scope’s variables even after the outer function has finished executing. This allows inner functions to “close over” and use variables from their outer scope, enabling data privacy and state management.
Addressing the Global Variables Suggestion
Some might suggest making all variables global for easier access, but this is a bad practice. Global variables can cause naming conflicts, unintended side effects, and make debugging harder. They also risk memory leaks since they persist throughout the application’s lifetime, even after functions using them finish. If references linger (e.g., in cached data or event listeners), the garbage collector can’t free the memory, leading to leaks. To avoid this, limit global variables and clean up references when no longer needed.