Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript and the DOM (Retiring) 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
seal-mask
.a{fill-rule:evenodd;}techdegree
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.