2. `forEach`
forEach
When to use: When you want to perform an operation on every element in an array.
Recall the ever so common 'for loop':
var numbers = [1, 2, 3, 4, 5];
for (var i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
This is a ton of syntax and incredibly laborious if we merely want to perform an action for each item in the array. That's where the forEach
array helper comes in handy. Here is a first example:
var numbers = [1, 2, 3, 4, 5];
numbers.forEach(function (number) {
console.log(number);
});
As you can see, forEach
is a function that takes an anonymous callback function as an argument and invokes this function for each item in the array. The first parameter in that anonymous callback function with be the current item in the array. As demonstrated below, the callback also takes 2 additional, optional parameters - the 'index' and 'array'.
forEach
from scratch
Often times it's helpful to reverse engineer what we're learning to get a deeper understanding. Let's see if we can rebuild forEach
from scratch. Here is what it might look like:
// Adding it to the Array's prototype so we can call it directly on arrays
Array.prototype.myForEach = function (callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
};
Note that we called it myForEach
instead of forEach
just to prove to you that we built a new method from scratch, entirely.
Go ahead and copy/paste this example below to see that it works:
// Adding it to the Array's prototype so we can call it directly on arrays
Array.prototype.myForEach = function (callback) {
for (let i = 0; i < this.length; i++) {
callback(this[i], i, this);
}
};
var numbers = [1, 2, 3, 4, 5];
numbers.myForEach(function (number) {
console.log(number);
});
Here are a few things to note about our myForEach
function (and forEach
):
- The parameter that we're calling
callback
is a placeholder for whatever function will get passed tomyForEach
when its invoked. In the case above, we passed in a function that logsnumber
. - When we invoke
callback
inside ofmyForEach
, we're passing in 3 arguments -this[i]
,i
, andthis
. That's because that's just howforEach
works:arr.forEach(function (currentValue, index, array) { // iterator });
Let's move into some exercises.
forEach
Exercise 1
Refactor the following code to use forEach
instead of a "for loop":
var saveUser = function (user) {
console.log('saving', user.name);
}
var saveUsers = function () {
var users = [
{ id: 15, name: 'Bob' },
{ id: 23, name: 'Jimbo' },
{ id: 35, name: 'Cathy' }
];
for (var i = 0; i < users.length; i++) {
saveUser(users[i]);
}
}
Click to See Answer
var saveUser = function (user) {
console.log("saving", user.name);
};
var saveUsers = function () {
var users = [
{ id: 15, name: "Bob" },
{ id: 23, name: "Jimbo" },
{ id: 35, name: "Cathy" },
];
users.forEach(function (u) {
saveUser(u);
});
};
forEach
Exercise 2
Use forEach
to calculate the volumes of each "box" in the boxes
array and populate volumes
with those figures. The volumes
array should have 5 numbers in it.
var boxes = [
{ length: 10, width: 15, height: 20 },
{ length: 15, width: 20, height: 25 },
{ length: 20, width: 25, height: 30 },
{ length: 25, width: 30, height: 35 },
{ length: 30, width: 35, height: 40 },
];
var volumes = [];
Click to See Answer
var boxes = [
{ length: 10, width: 15, height: 20 },
{ length: 15, width: 20, height: 25 },
{ length: 20, width: 25, height: 30 },
{ length: 25, width: 30, height: 35 },
{ length: 30, width: 35, height: 40 },
];
var volumes = [];
boxes.forEach(function (box) {
volumes.push(box.length * box.width * box.height);
});
^ There is actually a better way to do this! We'll learn about map
next!