Scope and Closures
Understand where variables are visible and how functions remember their surroundings.
Scope decides where a variable can be used. Variables declared with let and const are block scoped: they exist only inside the nearest pair of curly braces.
JavaScript
const site = "GateShala"; // global: visible everywhere below
function show() {
const message = "inside the function";
console.log(site, "-", message);
}
show();
if (true) {
let blockOnly = 42;
console.log(blockOnly);
}
console.log(typeof blockOnly); // not defined out here
Output
GateShala - inside the function 42 undefined
Shadowing
A variable in an inner scope can have the same name as one outside. Inside, the inner one wins; outside, nothing changes.
JavaScript
let level = "outer";
function test() {
let level = "inner";
console.log(level);
}
test();
console.log(level);
Output
inner outer
Closures
A function remembers the variables that were in scope when it was created, even after the outer function has finished. This combination is called a closure.
JavaScript
function makeCounter() {
let count = 0;
return function () {
count++;
return count;
};
}
const counterA = makeCounter();
const counterB = makeCounter();
console.log(counterA(), counterA(), counterA());
console.log(counterB());
Output
1 2 3 1
Each call to makeCounter creates a fresh count. Nobody outside can change it directly: closures give you private state.
A practical closure
JavaScript
function makeMultiplier(factor) {
return (n) => n * factor;
}
const double = makeMultiplier(2);
const triple = makeMultiplier(3);
console.log(double(7), triple(7));
console.log([1, 2, 3].map(triple));
Output
14 21 [ 3, 6, 9 ]