Why callbacks exist
Some functions know HOW to do something but not WHAT: a loop that knows how to repeat but not what to repeat each lap, an array method that knows how to visit every item but not what to do with each one. The missing piece arrives as an argument. A function passed into another function so it can be called there is a callback — the receiver "calls it back" at the right moment. This is the shape of most JavaScript APIs: unit 7's map and filter, browser event handlers ("when clicked, run this"), and timers all take callbacks.
function repeat(times, action) { for (let i = 1; i <= times; i++) { action(i); } } repeat(3, n => console.log(`Lap ${n}`));
Inside repeat, the parameter action is an ordinary variable that happens to hold a function (lesson 6-2 said functions are values), so action(i) calls it. The arrow you pass decides what each lap does — repeat never needs to know.
Code exercise · javascript
Run it. repeat owns the loop; the arrow you pass owns the body. Then change the 3, or make the arrow print n * 10, and run again.
Pass the function, do not call it
The classic callback bug is one pair of parentheses:
repeat(3, sayHi()); // WRONG: calls sayHi NOW, passes its return value repeat(3, sayHi); // right: passes the function itself
Parentheses mean "run this now". So sayHi() executes immediately and hands repeat whatever it returned — usually undefined — and the program crashes later when repeat tries to call undefined. The bare name sayHi hands over the function itself, ready to be called later. Named functions, function expressions, and arrows all work as callbacks; inline arrows are the everyday choice when the behavior is short.
Code exercise · javascript
Your turn. Write calculate(a, b, operation) that returns operation(a, b). Define add and multiply as arrow functions, then print calculate(4, 5, add), calculate(4, 5, multiply), and a third call that passes (x, y) => x - y inline with 10 and 3.
Quiz
function twice(fn) { fn(); fn(); } and a function greet exist. Which call is correct?