BuildBot

JavaScript, Refreshed

Functions, scope & closures

Lesson 2 of 5

What you'll learn

  • Treat functions as first-class values you can pass and return
  • Reason about lexical scope — where a variable is visible
  • Use a closure to keep private state alive between calls

In JavaScript a function is just a value. You can store it in a variable, put it in an array, pass it to another function, and return it from one. This is what "first-class functions" means, and it's the foundation for callbacks, array methods, and most functional patterns.

const double = (n) => n * 2;
const apply = (fn, x) => fn(x);

console.log(apply(double, 21)); // 42

Lexical scope

Scope is lexical: a function can see variables from the place it was written, not the place it's called. Inner scopes can read outer variables; outer scopes cannot reach in. This nesting is fixed at authoring time, which makes it predictable.

const outer = 10;
function makeAdder() {
  const inner = 5;
  return outer + inner; // can see both
}
// nothing outside makeAdder can see `inner`

Closures

A closure is what you get when a function outlives the scope it was created in but still remembers that scope's variables. The returned function keeps a live link to those variables — so you can build private state that nothing else can touch.

Each closure is independent

Call a closure-factory twice and you get two separate states. They share the code, not the captured variables — just like two counters that count on their own.

The challenge builds a counter whose count lives only inside the closure. There's no way to read or corrupt it from outside except through the methods you return.

A closure-based counter

Run it. The count is private — only the returned methods can touch it, and two counters stay independent.

Loading editor…

Next: working with arrays and objects, the data shapes you'll use everywhere.

Sign in to save your progress across devices.