0

I am confused why Javascript shows different behaviour when I use a looped element vs this keyword in a simple for loop. For example, when I run following loop, it gives error: cannot read property innerHTML of undefined

//get a handle on all digits
var digits = document.getElementsByClassName("digit");
for(var i=0; i<digits.length; i++) {
    digits[i].addEventListener("click", function() {
        var number = digits[i].innerHTML;    //error here
        console.log(number);
    })
}

But when I replace digits[i] with this, it works fine. My question is, what is different in the second case? (with this)

//get a handle on all digits
var digits = document.getElementsByClassName("digit");
    for(var i=0; i<digits.length; i++) {
        digits[i].addEventListener("click", function() {
            var number = this.innerHTML;    //this works as expected
            console.log(number);
        })
    }
software_writer
  • 3,941
  • 9
  • 38
  • 64
  • In the second code snippet, `this` inside the event handler refers to the element on which the event has occurred. – Tushar Feb 13 '16 at 17:31
  • The variable `digits` doesn't exist in the callback function. https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/README.md – Michelangelo Feb 13 '16 at 17:36
  • Thanks for the link! can you please explain why digits is not accessible inside the callback? – software_writer Feb 13 '16 at 17:42
  • @Mikey: Of course `digits` exist. JavaScript is lexically scoped and every function is a closure. The issue is with `i`. The duplicate explains what the issue is. – Felix Kling Feb 13 '16 at 17:51
  • @Mikey: That's not the issue either :) `i` *is* accessible, but it doesn't have the correct value at the moment the function is executed. This has nothing to do with global or non-global variables. See the duplicate question. – Felix Kling Feb 13 '16 at 17:58
  • Just to clarify: The issue has nothing to do with `this`. Loops have no impact on the value of `this`. – Felix Kling Feb 13 '16 at 18:00
  • The `for` loop will execute as the page loads, so the `i` variable will have a value of `digits.length`at the time when the `digit` get clicked – The Process Feb 13 '16 at 18:00
  • @FelixKling Yes you stand correct. `i` is indeed available in the callback. I don't know why I thought it wouldn't be. The issue is indeed with the value of `i`. It keeps the value of the last iteration. – Michelangelo Feb 13 '16 at 18:04
  • @Mikey: Maybe it's just one of these days :) – Felix Kling Feb 13 '16 at 18:05
  • @FelixKling Well working on a Saturday is not the best idea to keep your mind sharp ;). – Michelangelo Feb 13 '16 at 18:07

0 Answers0