Javascript · Functions (Advanced)
Callbacks (Intro)
The full text of this chapter, to read or revisit. To practise, do the exercises.
▶ Do the exercises
Exercise 1 — What Is a Callback?
In the previous chapter, you passed a function to another function. This has a name: the function you pass is a callback. Here's a classic example: `repeat` takes a number and an action, and runs that action as many times as asked.
function repeat(times, action) { for (let i = 0; i < times; i++) { action(); } } const cheer = () => console.log("Go Pyrochu!"); repeat(3, cheer);
`repeat` doesn't know what `action` does. It only knows when to call it. That separation is the whole point: the same `repeat` works with any action.
Exercise 2 — Callbacks With Parameters
The receiving function can pass arguments to the callback when it calls it. Here each member of the team is handed to the callback one by one:
function forEachMember(team, action) { for (let cdm of team) { action(cdm); } } const greet = (name) => console.log("Hello " + name + "!"); forEachMember(["Aquachu", "Zap"], greet);
Exercise 3 — Quiz: Who Calls Whom?
In `repeat(3, cheer)`, which statement is true?
Options
• repeat calls cheer three times
• cheer calls repeat three times
• cheer runs once, before repeat
• Neither function runs
Hint : The callback is handed over, then called from inside the other function.
Exercise 4 — Repeat With a Counter
Complete `countdown` so it passes the current number to the callback, then use `show` as the callback.
function countdown(start, action) { for (let n = start; n > 0; n--) { action(____); } } const show = (n) => console.log(n + "..."); countdown(3, ____);
Options: n show start show() action
Hint : Pass the loop variable to the callback, and pass the function without calling it.
Exercise 5 — Using the Callback's Result
A callback can return a value, and the receiving function can use it. Here the callback decides which members count:
function countIf(values, test) { let count = 0; for (let v of values) { if (test(v)) { count++; } } return count; } const levels = [3, 12, 7, 15]; const isHigh = (level) => level >= 10; console.log(countIf(levels, isHigh));
`countIf` doesn't know what "high" means. The callback does. Swap it for another test and the same function counts something else:
Exercise 6 — Quiz: Counting With a Callback
What does this code print?
function countIf(values, test) { let count = 0; for (let v of values) { if (test(v)) { count++; } } return count; } const isSmall = (n) => n < 5; console.log(countIf([1, 9, 4, 6, 2], isSmall));
Options
• ```3```
• ```2```
• ```5```
• ```true```
Hint : Apply the test to each value and count the true answers.
Exercise 7 — Why Callbacks Matter
Callbacks let you write a function once and customise its behaviour at each call. Compare: without a callback, you'd need one function per case.
function transformAll(values, transform) { const result = []; for (let v of values) { result.push(transform(v)); } return result; } const double = (n) => n * 2; const addTen = (n) => n + 10; console.log(transformAll([1, 2, 3], double)); console.log(transformAll([1, 2, 3], addTen));
Coming next
JavaScript arrays have built-in functions that work exactly like `forEachMember`, `countIf` and `transformAll`. They're called `forEach`, `filter` and `map`, and they're the subject of the next class.
Exercise 8 — Custom Test
Complete `keepIf` so it adds a value to the result only when the callback says so, then count the electric moves.
function keepIf(values, test) { const kept = []; for (let v of values) { if (____(v)) { kept.____(v); } } return kept; } const moves = ["Spark", "Splash", "Thunder"]; const isElectric = (move) => move === "Spark" || move === "Thunder"; console.log(keepIf(moves, ____).length);
Options: test push isElectric v isElectric() unshift
Hint : Inside, the callback goes by its parameter name. Outside, pass the function itself.
Exercise 9 — Callback Vocabulary
Match each term with its description.
Items to match
• Callback
• repeat(3, cheer)
• action(cdm)
• The callback's return value
Definitions
• A function passed to another function
• cheer is the callback
• Calling the callback with an argument
• Can be used by the receiving function
Exercise 10 — Quiz: Order of Output
What does this code print?
function twice(action) { console.log("start"); action(); action(); console.log("end"); } twice(() => console.log("hit"));
Options
• ```start```, ```hit```, ```hit```, ```end```
• ```hit```, ```hit```, ```start```, ```end```
• ```start```, ```end```, ```hit```, ```hit```
• ```start```, ```hit```, ```end```
Hint : Follow the body of twice line by line.
Exercise 11 — Team Processor
Write a generic function that runs a callback on every member of a team, then use it with two different callbacks.
Step 1: `processTeam(team, action)` calls `action` once per member, passing the member's name and its position counted from 1. Step 2: write a callback `announce(name, position)` that prints `"position. name"`, for example `"1. Aquachu"`. Step 3: write a callback `cheer(name, position)` that prints `"Go name!"`. Step 4: run `processTeam` with `announce`, then with `cheer`.
Expected output:
1. Aquachu 2. Pyrochu 3. Zap Go Aquachu! Go Pyrochu! Go Zap!
Starter code
const team = ["Aquachu", "Pyrochu", "Zap"]; // Write your functions here // Use them here
Back to the course