# JavaScrip forEach loop

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:

```js
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.

`index`

The 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](/getting-dom-elements-with-javascript):

- `getElementsByClassName()` produces an
  [`HTMLCollection`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection)
- `querySelectorAll()` produces a
  [`nodeList`](https://developer.mozilla.org/en/docs/Web/API/NodeList).

> These return not arrays of nodes but nodeLists, which are freaky weird things
> — [Douglas Crockford](https://youtu.be/Fv9qT9joc0M?t=50m53s)

Here’s our super simple HTML that we’re going to be working with:

```html
<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 `Array`s `forEach` method directly, like so:

```js
// 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:

```js
;[].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:

```js
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:

```js
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:

```js
;['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](/javascript-manipulating-objects-with-object-keys/).
