All the Loops

Modern JavaScript supports many different looping constructs. I often use these different constructs for working with arrays. This is a reference, for myself and for others, written to augment the existing MDN documentation.

An array arr is defined for all the below examples. The sample code for each looping construct performs the same behavior.

§ Table of Contents

§ Basic Loop Constructs

§ for statement

This is the standard C-style loop.

let arr = ["a","b","c","d"]
for(var i = 0; i < arr.length; i++) {
    console.log(i, arr[i])
}

§ do...while statement

Repeat until condition is false.

var i = 0;
do {
    console.log(i, arr[i])
    i++
} while (i < arr.length)

§ while statement

Repeat while condition is true.

var i = 0
while (i < arr.length) {
    console.log(i, arr[i])
    i++
}

§ Object Loop Constructs

§ for...in statement

Executes on the properties (indices) of an object. In JavaScript, Arrays are objects, so this is valid.

for(var i in arr) {
    console.log(i, arr[i])
}

§ for...of statement

Loops over the values of iterable objects including Array, Map and Set.

var i = 0
for(var val of arr) {
    console.log(i, val)
    i++
}

Note that for...of loops the values, while for...in loops the properties/indices.

§ Functional Loop Constructs

Multiple functional-style prototypes exist on the Array object. Handy for list comprehensions or for rewriting complicated loops with simpler syntax, especially with reduce and filter. Promotes immutability.

§ map prototype

Calls a callback function once for each element and returns the resulting array. This map callback prints trivial debug information for the array.

function callback(value, index, array) {
    console.log(index, value)
    return `value: ${value}, index: ${index}`;
}
var mappedArr = arr.map(callback)

Does not mutate the source array.

§ reduce prototype

Calls a reducer callback to accumulate the array values into a single value. This reducer callback joins the array with commas, similar to Array.prototype.join().

function reducer(accumulator, value, index, array) {
    console.log(index, value)
    return accumulator + "," + value
}
var initialValue = ""
var joined = arr.reduce(reducer, initialValue)

Does not mutate the source array. Note that if the initialValue parameter is not included in the arr.reduce() call, the initial value is set to array[0] and that first index will be skipped in the loop.

§ filter prototype

Calls a filter callback to create a filtered array from the source array. The filter prototype is very useful for cleaning sparse arrays as illustrated below or for, of course, filtering data based on a condition in a more readable manner than with a for loop.

function filter(value, index, array) {
    console.log(index, value)
    return typeof value !== 'undefined'
}
var filtered = arr.filter(filter)

Does not mutate the source array.

§ Addendum

Discuss on HN