Pass behavior as an argument
A higher-order function accepts a function, returns one, or both. A callback is a function supplied for another operation to invoke. Callbacks may run synchronously or asynchronously; the word callback alone does not tell you when they execute.
function transformEach(values, transform) {
const result = [];
for (const value of values) result.push(transform(value));
return result;
}
const marks = [10, 20, 30];
const doubled = transformEach(marks, value => value * 2);
console.log(doubled); // [20, 40, 60]
console.log(marks); // [10, 20, 30]transformEach controls traversal while the callback controls the transformation. It invokes the callback immediately during its loop. By contrast, a timer callback runs later.
Return a specialized function
function atLeast(minimum) {
return value => value >= minimum;
}
const isPassing = atLeast(40);
console.log([35, 40, 82].filter(isPassing)); // [40, 82]The returned callback closes over minimum. This is useful when one generic operation needs a small configured rule.
Pass the function, not its result
setTimeout(showMessage, 100) passes a function for later execution. setTimeout(showMessage(), 100) calls it immediately and passes whatever it returned. For arguments, wrap the call in a function: setTimeout(() => showMessage('Ready'), 100).
Callback contracts
Document the arguments, return value, execution timing and error behavior. A callback used by map must return the mapped value; one used by forEach has its return value ignored. A synchronous try/catch around timer registration cannot catch an exception thrown later inside the timer callback.
Practice
- Pass a square callback to transformEach; [2,3] should become [4,9].
- Build a predicate for scores at least 80.
- Log before and after a synchronous array callback, then repeat with setTimeout to compare ordering.
- Explain why transformEach does not itself decide whether to double, square or format a value.