Level: Intermediate | Player: 11_Array_Higher-order function
Learning Objectives
- Explains the meaning of lexical scope.
- Know what a closure is and when it is created.
- Create a counter with a private state using a closure.
- Separate the Public/Private member with a module pattern (IIFE).
- Solve common loop variable capture bugs with
let.
1. Lexical scope
The scope of a function is determined by its declared position. This is not a call location.
const x = 1;
function outer() {
const y = 2;
function inner() {
return x + y; //outer/global variable reference
}
return inner;
}
2. Closure
A closure is a phenomenon in which a function remembers the environment (variable) in which it was created. Even after outer() is returned, inner can still use y.
const fn = outer();
fn(); // 3
3. Private status: counter
Closures allow you to create states that cannot be directly accessed from the outside.
function makeCounter() {
let count = 0;
return {
inc() { count += 1; return count; },
get() { return count; },
};
}
const c = makeCounter();
c.inc(); c.inc(); c.get(); // 2
4. Module pattern (IIFE)
An immediate function expression creates a scope that executes only once and returns only the members you want to make public.
const Logger = (() => {
let level = "info";
function setLevel(l) { level = l; }
function log(msg) { console.log(`[${level}] ${msg}`); }
return { setLevel, log };
})();
Core example
| file | Contents covered |
|---|---|
01_scope.js |
Block/Function scope, let/const/var |
02_closure.js |
Closure Basics |
03_counter.js |
Private status counter |
04_module_pattern.js |
IIFE module pattern |
⚠️ Common Mistakes
- The loop variable declared as
varis incorrectly captured in the setTimeout callback → Uselet. - Forget that GC is not possible because closures are holding memory (be careful of large amounts of data).
- Trying to change the closure variable directly from outside (impossible).
functionConfusing the difference between declaration hoisting and expression hoisting.- Confusion due to shadowing external and internal variables of the same name.
❓ Frequently Asked Questions (FAQ)
Q1. When is a closure created? A. The moment a function is defined, if it references the external environment, a closure is created.
Q2. Are closures bad for performance? A. Generally negligible. However, if you hold a large object, memory leaks are possible.
Q3. Block scope of let and const? A. The effective scope is limited to { } units.