11 Ways of iterating over a NodeList
Tags: javascript, webdev, tutorial, watercooler
Published: 2020-11-06 20:37:51

---
title: 11 Ways of iterating over a NodeList
published: true
description: 12 Ways of iterating over a NodeList
tags: javascript, webdev, tutorial, watercooler
cover_image: https://miro.medium.com/max/700/0*aH8YUI7nqAZ6b-V_.png
---

Have you ever thank on how many ways we can iterate over a NodeList? I myself use a single workaround for a job but I was thinking about and I realized there's much more. Let’s look at some options

Getting our NodeList:

```javascript
  const elements = document.querySelectorAll('.selector');
```

Let's begin with the classic forEach

Note that not all browsers support forEach on NodeLists, but for those that it works:

```javascript
elements.forEach((element) => {
  element.addEventListener('click', () => {
    console.log("iteration worked", element);
  });
});
```

Another way to use forEach with call method, can seem a bit tricky but it works and has more wide browser support:

```javascript
[].forEach.call(elements, function(element) {
  console.log("iteration worked", element);
});
```

Take care as this last way to do it access the created empty array's prototype method and using call allows the NodeList to take advantage, but this even it can work is a bad practice, let's see the following example and why it's bad:

```javascript
NodeList.prototype.forEach = Array.prototype.forEach;
```

This will extend the existing DOM functionality through prototypes. This is considered as a bad practice as it can lead to tones of issues.

Some of the issues are that we are caching the selector, but we’re not caching the array or even what the loop is doing, which means we can’t reuse the method.
It also lacks of Array methods (we only extended forEach and of course it's not recommended to extend all of them even you do it only when needed).

NodeLists and Arrays are different tools so we can "cast" when needed:

```javascript
var myArrayFromNodeList = [].slice.call(document.querySelectorAll('.selector'));
```

But that's another Array.prototype hack and I don't recommend it either. By the way it does not work with IE (who cares about IE anyway?)

How can we achieve that on a better way?

```javascript
var myNodeList = document.querySelectorAll('.selector');
var myArrayFromNodeList = []; // empty at first

for (var i = 0; i < myNodeList.length; i++) {
  myArrayFromNodeList.push(myNodeList[i]); // push it, babe
}
```

Check it:

```javascript
  console.log(myNodeList); // NodeList
  console.log(myArrayFromNodeList); // Array of Nodes
```


OK let's go back to the main thread with the for loop:

```javascript
for (i = 0; i < elements.length; ++i) {
  console.log("iteration worked", elements[i]);
}
```

The forEach... again?

```javascript
// forEach method, could be shipped as part of an Object Literal/Module

var forEach = function (array, callback, scope) {
  for (var i = 0; i < array.length; i++) {
    callback.call(scope, i, array[i]);
  }
};

// optionally change the scope as final parameter too
forEach(elements, function (index, value) {
  console.log(index, value);
});
```

<small>Disclaimer: please this is for educational purposes but don't name your vars with forEach or any other built-in method.</small>

Now it's the time to talk about for...of loops:

```javascript
for (const element of elements) {
  element.addEventListener('click', () => {
    console.log("iteration worked", elements);
  });
}
```


Well if you thank this is the end... it's not! we've not talked about the ES6 Spread Operator!

```javascript
[...elements].forEach((element) => {
  element.addEventListener('click', () => {
    console.log("spread forEach worked", element);
  });
});
```

And, of course two more classics, the while loop:

```javascript
let i = 0;
while(elements[i] !== undefined) {
  console.log(elements[i]);
  ++i;
}
```

And the do...while!

```javascript
i = 0;
do {
  console.log(elements[i]);
  ++i;
} while (elements[i] !== undefined);
```

Remember that the do...while will always run once before checking the condition so you need to ensure it will be true at least once unless you want an error which can be bad or worse depending on the stuff you do in between the brackets. For example

```javascript
i = undefined;
do {
  console.log(elements[i]);
  ++i;
} while (elements[i] !== undefined);
```

will return a <code>NaN</code> or eventually <code>undefined</code>


<hr/>

And that's all, hope you learnt about what you can do and about what you must don't. Do you know another way to iterate over NodeLists?

Bonus:
As @jwp suggested:
```javascript
Array.from(nodelist)
```
Once we created an array from a nodelist we can iterate over it through any <a href="https://www.w3schools.com/js/js_array_iteration.asp">array iteration</a> method.

Do you have any question? Let me know in the comment section :smile:


Best regards,

Joel