3

I ran into this code earlier and I don't understand why the list item's number on the array index is logged to the console when you click on a list item. Shouldn't the console log 4 every time a list item is clicked? Better yet, shouldn't it be impossible to click on any of the list items because items[x] is equal to 4? What am I not understanding here?

html

<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

javascript

var items = document.getElementsByTagName("li");

for(let x=0; x < items.length; x++){
  items[x].onclick = function(){
    console.log(x);
  }
}
Will
  • 97
  • 8
  • 2
    Reverse question of https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – epascarello Nov 15 '19 at 04:15
  • 1
    https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var – epascarello Nov 15 '19 at 04:16
  • looking for more of an explanation rather than a solution. – Will Nov 15 '19 at 04:18
  • 1
    Because that is how let works. Read MDN's explanation. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let neither of the links are solutions, they tell you the difference. And your question is opposite of 100's of questions that say "Why is x always 4?" And the solution is, "Use let instead of var" – epascarello Nov 15 '19 at 04:20

2 Answers2

3

Why do you think console log should print 4 every time a list item is clicked?

let defines its own scope in JavaScript, that's why the current iteration value is retained afterwords (when the element is clicked).

Though you can get your expected output with var:

var items = document.getElementsByTagName("li");

for(var x=0; x < items.length; x++){
  items[x].onclick = function(){
    console.log(x);
  }
}
<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>
Mamun
  • 66,969
  • 9
  • 47
  • 59
  • Well, I am not trying to do anything really. I just don't understand why it is the way it is and was seeking more of an explanation rather than a solution. I probably should have made that clearer. I do appreciate your response otherwise. – Will Nov 15 '19 at 04:17
  • @Will, that is because of the individual scope created with `let`:) – Mamun Nov 15 '19 at 04:21
2

You get all 4 list items and assign them to items. Then you loop through them by index, starting at index 0 and going through 3, assigning them an onClick which is a function that prints to the console whatever the index was (0,1,2, and 3).

Matt
  • 560
  • 1
  • 5
  • 12
  • One other question if it is assigning onClick to each item, how is it starting with 0? wouldn't it start with 1 since it would have already added 1 to x when going through the loop the first time? – Will Nov 15 '19 at 04:27
  • 1
    The update part of the for loop occurs after a loop iteration. So for the first loop it will be 0 because x was initialized as 0. It updates again after each subsequent iteration. – Matt Nov 15 '19 at 04:31