The forEach loop for beginners, and how to use it with a nodeLists, and
HTMLCollections.
Array.prototype.forEach()
So the forEach loop loops and array and gives access to the current item
through a callback function. It doesn’t return anything.
Here’s the basics:
var normalArray = ['foo', 'bar', 'baz', 'fooz']
normalArray.forEach(function (currentValue, index, array) {
console.log(currentValue + ' - ' + index + ' - ' + array)
})The callback params:
currentValue- The current element of the array being processed.
indexThe index of the
currentValue.array- The original array the loop was call upon.
Looping HTMLCollection or a nodeList with forEach
When querying elements on the page, the resulting collection is no an array, but DOM queries return several collection types:
getElementsByClassName()produces anHTMLCollectionquerySelectorAll()produces anodeList.
These return not arrays of nodes but nodeLists, which are freaky weird things — Douglas Crockford
Here’s our super simple HTML that we’re going to be working with:
<div class="module"></div>
<div class="module"></div>
<div class="module"></div>HTMLCollection or a nodeList are not arrays, per se, they’re "array-like
objects", and we can’t use forEach right out the box. But what we can do is to
call the Arrays forEach method directly, like so:
// Grab the wanted elements
var htmlCollection = document.getElementsByClassName('module')
Array.prototype.forEach.call(htmlCollection, function (element) {
console.log(element.tagName)
})The Array.prototype can be truncated to a pair of brackets [], like so:
;[].forEach.call(htmlCollection, function (element) {
console.log(element.tagName)
})Or you can spread the nodeList or the HtmlCollection and then use it like
any other array:
var htmlCollection = [...document.querySelectorAll('.module')]
htmlCollection.forEach(function (element) {
console.log(element.tagName, 'foo')
})Just as a reminder that the good old for loop works great also:
for (var i = 0; htmlCollection.length < i; i++) {
console.log(htmlCollection[i].tagname)
}Things forEach can’t do
There are things forEach can’t do. The two words "for" and "Each" are taken
very literally, you’re about to iterate every single element in the array,
break or continue can’t be used. Here’s a non working example:
;['foo', 'bar', 'baz'].forEach(function (element, index) {
if (index > 3) {
// Does not work
break
// Likewise for:
// continue
}
console.log('Current ' + element + ', Index ' + index)
})You get an error: Uncaught SyntaxError: Illegal break statement.
Or just use a for loop if you need to break. I have a post about looping and
manipulating objects that has a lot of good stuff related to this,
have look.