JavaScript JavaScript and the DOM Responding to User Interaction Listening for Events with addEventListener()

why can't I use "var" in for loop

When I use var in the for loop to set i = 0. I get errors. When I change it to "let" it works. I have not really learned about let so I always use var. why isn't it working now?!

const listItems=document.getElementsByTagName("li");

for(var i=0; i < listItems.length; i++){ listItems[i].addEventListener('mouseover', () => { listItems[i].textContent=listItems[i].textContent.toUpperCase(); });

listItems[i].addEventListener('mouseout', () => { listItems[i].textContent=listItems[i].textContent.toLowerCase(); }); }

2 Answers

What are the errors you are getting? From looking at this code it would not be an 'error' but how javascript works in general.

I assume you are expecting the mouseout event to refer to the index of the listItems?

However, what instead happens, the index always refers to the last item in the array when the mouseout event occurs?

If this is what you are experiencing it is because of the asynchrounous nature of javascript. var i = 0 in your for loop will hoist i into the global scope. So i will constantly update until it reaches the end of the array.

This is solved with using let i = 0. that is because let will not hoist into the global scope, but instead remains in the scope of the for loop. Letting your event listeners refer to the correct index.

In the days before let this had to be solved using closures.

If this does not make any sense - I suggest watching the closures lecture on treehouse. That example is pointed out in there and was a huge 'aha' moment for me.

Akash Sharma
Akash Sharma
Full Stack JavaScript Techdegree Student 14,147 Points

So if you could help me understand that each iteration if let i = some number, those mouseover and mouseout functions are stored somewhere in the script as we loop over them?

Like it would be exactly identical to a script if we manually added the mouseover and mouseout for each element in the HTML Collections listItems?

Thanks

They are not stored somewhere in the script as such. But you get the point by raising your second point. By using 'let i = some number' we make sure that 'i' inside the for loop is always referring to the actual iteration.

If you go through the loop it actually makes sense. You load the page, but you are not immediately hovering over the list items. What is happening is that the for loop loops through all iteration and each time the mouseover event listener is updated with the next index and that is because var i = some number is hoisted into the global scope.