Higher Order Functions
CSCI 344: Advanced Web Technologies
Spring 2025
Announcements
Outline
Outline
Intro to Higher-Order Functions
Simple Example: “Do something in X seconds”
// callback function 1
function sendAnEmail() {
console.log("Pretend the function sends an email...");
}
// callback function 2
function drawSomethingToTheScreen() {
console.log("Pretend the function draws on the screen...");
}
// Higher order function: “Call callback function in X milliseconds”
setTimeout(sendAnEmail, 500);
setTimeout(drawSomethingToTheScreen, 1000);
See: 00-example-callback-functions.js
Demo (lecture files)
What just happened?
Examples:
Why would you want to do this?!
Example: Iteration
There are many computation actions that are so common in JavaScript that they’ve been abstracted into “higher order functions.” One example is iteration:
Given that this is a common design pattern, why not separate things out:
Example: The forEach Higher Order Function
In this example, the printItemToConsole function is invoked for every element in the list:
// list�const fruit = ['apple', 'orange', 'banana', 'mango', 'peach'];
// function to be invoked for each list item�const printItemToConsole = item => console.log(item);
// putting it all together: print each item in the list to the console:�fruit.forEach(printItemToConsole);
Example: Iteration with anonymous function
You can also just specify the function definition as an argument directly:
const fruit = ['apple', 'orange', 'banana', 'mango', 'peach'];��fruit.forEach(item => console.log(item));�
…or do it all in one line!
['apple', 'orange', 'banana', 'mango', 'peach'].forEach(
item => console.log(item);
);
What else could you do?!
You can also just specify the function definition as an argument directly:
const fruit = ['apple', 'orange', 'banana', 'mango', 'peach'];�
fruit.forEach(item => console.log(item));
// other stuff you might want to do:
fruit.forEach(drawToScreen);�fruit.forEach(appendToObject);�fruit.forEach(getNutrientValue);�fruit.forEach(addToDropdownMenu);
Common Error: Definition v. Invocation
const fruit = ['apple', 'orange', 'banana', 'mango', 'peach'];
// function 1 (printing to the console):�const printItemToConsole = item => console.log(item);
// what’s wrong with this?
fruit.forEach(printItemToConsole());
Outline
What is forEach actually doing?
Example: forEach “Under the Hood”
class SuperArray extends Array {
forEach(callbackFn) {
for (let i = 0; i < this.length; i++) {
// invokes the callback function with all three parameters:
callbackFn(this[i], i, this);
}
}
}
const myArray = new SuperArray(1, 2, 3, 4, 5);
�const myCallback(item, i, arr) => console.log(`${i}: ${item} ${arr}`)
myArray.forEach(myCallback);
map
The map() method creates a new array from calling a function for every array element.
Example:
const numbers = [65, 44, 12, 4];
const squareEm = num => num ** 2;
const newArr = numbers.map(squareEm);
Map Demo
filter
The filter() method creates a new array filled with elements that pass a test provided by a function.
�Example:
const my_nums = [1, 2, 3, 4, 5];
const nums_greater_than_2 = my_nums.filter(item => item > 2);
console.log(nums_greater_than_2);�
filter Demo
reduce
The reduce() method executes a reducer function for array element. It returns a single value: the function's accumulated result.
�Example:
const sum_of_nums = my_nums.reduce((a, b) => a + b);
console.log(sum_of_nums);
Parameters for reduce and the reducer function
callbackFn – Executed for each element in the array. Its return value becomes the value of the accumulator parameter on the next invocation of callbackFn. Arguments:
initialValue Optional
A value to which accumulator is initialized the first time the callback is called. If initialValue is specified, callbackFn starts executing with the first value in the array as currentValue.
reduce Demo