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

Eduardo Calvachi
Eduardo Calvachi
6,049 Points

Event Callback Function Context Issue

FYI, if you make the for loop iterator var i = 0 instead of let i = 0, like so:

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

You will get a:

Uncaught TypeError: Cannot read property 'textContent' of undefined

This tripped me up but once I found it I think I understand why that happens. I think it's because let does provide context of it's variable to the body of the callback function, whereas var does not provide that context. Does that sound about right?

1 Answer

jsdevtom
jsdevtom
16,963 Points

Yes. See this explanation of var vs let

Basically, when javascript is evaluated, var is hoisted which looks like this does this:

var i
for (i = 0; i < listItems.length; i += 1) {
    ....
}

whereas let does this:

//let is not defined outside of the for block
for (let i = 0; i < listItems.length; i += 1) {
    ....
}

and so when you actually mouse over something, var i has a value of listItems.length + 1. Say listItems.length is 10. When you actually mouse over something i is 11 so there is no listItems[11] and thus there is an error

I've found the easiest way to learn javascript is to look at the code using chrome devtools. You can find a tutorial here and by reading these open source books. You will go from noob to top 1%

ywang04
ywang04
6,735 Points

Just a quick question regarding difference between var and let. I am not sure why i can be printed out as different value (0,1,2,3,4) in each iteration of the loop while the i is 5 in your explanation? Thanks a lot.

for (var i=0;i<5;i++) {

  console.log(i);

}

The printed result is 0,1,2,3,4.