Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to loop through a set of elements in JavaScript?

In the past and with most my current projects I tend to use a for loop like this:

var elements = document.getElementsByTagName('div'); for (var i=0; i<elements.length; i++) {     doSomething(elements[i]); } 

I've heard that using a "reverse while" loop is quicker but I have no real way to confirm this:

var elements = document.getElementsByTagName('div'),      length = elements.length;  while(length--) {     doSomething(elements[length]); } 

What is considered as best practice when it comes to looping though elements in JavaScript, or any array for that matter?

like image 802
James Avatar asked Oct 01 '08 11:10

James


People also ask

Can you loop through a set in JavaScript?

Use the forEach() method to iterate over the elements in a Set . The forEach method takes a function that gets invoked once for each value in the Set object. The forEach method returns undefined .

Which loop is more efficient in JavaScript?

The fastest loop is a for loop, both with and without caching length delivering really similar performance.

How do you iterate through an element in JavaScript?

After selecting elements using the querySelectorAll() or getElementsByTagName() , you will get a collection of elements as a NodeList . To iterate over the selected elements, you can use forEach() method (supported by most modern web browsers, not IE) or just use the plain old for-loop.

What is the safest way to loop through an array in JavaScript?

You can use a for loop to iterate over arrays, NodeLists, and other array-like objects. This is the old-school way to loop over things. In the first part of the loop, before the first semicolon, we set a counter variable (typically i , but it can be anything) to 0 .


2 Answers

Here's a nice form of a loop I often use. You create the iterated variable from the for statement and you don't need to check the length property, which can be expensive specially when iterating through a NodeList. However, you must be careful, you can't use it if any of the values in array could be "falsy". In practice, I only use it when iterating over an array of objects that does not contain nulls (like a NodeList). But I love its syntactic sugar.

var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];  for (var i=0, item; item = list[i]; i++) {   // Look no need to do list[i] in the body of the loop   console.log("Looping: index ", i, "item" + item); } 

Note that this can also be used to loop backwards.

var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];      for (var i = list.length - 1, item; item = list[i]; i--) {   console.log("Looping: index ", i, "item", item); } 

ES6 Update

for...of gives you the name but not the index, available since ES6

for (const item of list) {     console.log("Looping: index ", "Sorry!!!", "item" + item); } 
like image 182
Juan Mendes Avatar answered Sep 22 '22 05:09

Juan Mendes


Note that in some cases, you need to loop in reverse order (but then you can use i-- too).

For example somebody wanted to use the new getElementsByClassName function to loop on elements of a given class and change this class. He found that only one out of two elements was changed (in FF3).
That's because the function returns a live NodeList, which thus reflects the changes in the Dom tree. Walking the list in reverse order avoided this issue.

var menus = document.getElementsByClassName("style2"); for (var i = menus.length - 1; i >= 0; i--) {   menus[i].className = "style1"; } 

In increasing index progression, when we ask the index 1, FF inspects the Dom and skips the first item with style2, which is the 2nd of the original Dom, thus it returns the 3rd initial item!

like image 34
PhiLho Avatar answered Sep 22 '22 05:09

PhiLho