3

I made a closure function with the help of google. The function works as it should. However, I'm not sure to know how it works.

function ShowQuestion(i) {
  console.log(i); // here 1 to 10 are logged immediately.
  return function() {
    console.log(i); // here the number are only logged when I mouse over on any li.
  }
}

setTimeout(function() {    
  for (i = 0; i < document.getElementById('Previousli').getElementsByTagName('ul')[0].children.length; i++) {
    document.getElementById('Previousli').getElementsByTagName('ul')[0].children[i].onmouseover = ShowQuestion(i);
  }    
}, 10000);

First of all, I'm wondering why the first console.log(i) log 1 to 10 immediately after the 10 seconds time out, but the second console.log(i) log the "index" only when I mouse over a li?

yuriy636
  • 11,171
  • 5
  • 37
  • 42
IssacNolan
  • 43
  • 3

1 Answers1

6

I'm wondering why the first console.log(i) log 1 to 10 immediately after the 10 seconds time out

Because the timeout callback has a loop and calls ShowQuestion in a loop. The first statement of ShowQuestion is the console.log, so you see all of those, one right after another, as that loop runs.

but the second console.log(i) log the "index" only when I mouse over a li?

Because ShowQuestion returns a function; the loop code assigns that function to the onmouseover property of the element, making it an old-fashioned event handler for the mouseover event. The function created by ShowQuestion isn't run until/unless that event occurs, and is re-run whenever that event occurs.

You may be wondering why/how that event handler can show i when i is an argument provided to ShowQuestion and by the time the handler is run by the mouseover event, ShowQuestion has already returned. The answer is that the function ShowQuestion creates is a closure over the context of that specific call to ShowQuestion, including the in-scope parameters and variables. So each of the copies of i from each of the calls to ShowQuestion survives, even though the call to ShowQuestion it relates to has completed.

More:

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Ah my eyes are open now. Thank you sir! Basically, ShowQuestion function run 10 times right after the timeout then never again? Is the loop create 10 differents mouse over event, one for every li element? – IssacNolan Sep 03 '17 at 09:25
  • @IssacNolan: That's it exactly. :-) – T.J. Crowder Sep 03 '17 at 09:27