Closures & private state
Functions that remember
Lesson 1 of 20 · 10 min · Module 1: Functions, deeper
A function created inside another function keeps access to the variables around it, even after the outer function has finished. That is called a closure, and it is how JavaScript keeps data private without classes.
Start this lesson →Free. No installation: you write and run the code in your browser, and it is checked automatically.
By the end, you’ll be able to…
- Explain what a closure is
- Keep state private inside a function
- Create independent instances with a factory function
The idea
Each call of the outer function creates new variables, and the inner functions it returns share exactly those variables. Nothing outside can read or change them except through the functions you return.
function makeGreeter(greeting) {
return name => greeting + ", " + name + "!";
}
const hello = makeGreeter("Hello");
console.log(hello("Mia"));
01Functions carry their surroundings
When makeGreeter returns the arrow function, the variable greeting stays alive because the arrow function still uses it. Every function in JavaScript remembers the scope it was created in.
02One call, one private world
Each call of createCounter makes a new current variable. The next and reset functions returned by that call share it, but a second counter gets its own.
function makeCounter() {
let count = 0;
return () => ++count;
}
const a = makeCounter();
const b = makeCounter();
console.log(a(), a(), b());1 2 103Private by design
Because current is a local variable and not a property, Object.keys(counter) only shows next and reset. Other code cannot set the counter to a wrong value by accident.
Your turn
createCounter(start = 0, step = 1). It returns an object with next(), which returns start on the first call, then start + step, and so on, and reset(), which makes the next call of next() return start again. Two counters must be independent, and the current value must not be visible as a property.What the checks look for
- Counts from the default start
- Uses a custom start and step
- reset() starts over
- Counters are independent and keep their value private
Take this with you
A closure is a function plus the variables it remembers.
Go a little further
Add a peek() method that returns the last value without advancing the counter.