2

I am new to Javascript and have came across to the topic of stack. In the following piece of code (which is simple in order to focus on basics instead of syntax), I can clear timerID inside of my function expression variable. It is quite common to do so, but my question is how the stack is made here? To be more clear, how the order of things goes on to clear the variable in which the clearer itself lives? And how the "console.log('DONE!')" is called after clearInterval()?


function countNumbers(number){
  var timer = setInterval(function(){
    number++;
    if(number >= 10){
      clearInterval(timer);
      console.log('DONE!');
    }
    else {
      console.log(number);
    }

  },1000)
}
BaN
  • 105
  • 9
  • It's called a closure. See my answer to this other question for how it works: https://stackoverflow.com/questions/26061856/javascript-cant-access-private-properties/26063201#26063201 – slebetman Sep 10 '19 at 19:01

1 Answers1

1

When a inner function is maintaining a reference to a variable of an outer function in JavaScript a clousure is formed, that is the members of the outer function is not destroyed when the outer function is done running since it's variables are still being referred from another function.

This is because when a function is executed a new Execution Context is created for that function's environment. It maintains a scope chain and is then pushed to the execution stack in the order of execution.

There is a global Execution context, then the invocation of the countNumbers creates its own execution context and finally the execution context of the callback is created. The callback function execution context maintains a pointer to the scope of the countNumbers function's execution context which maintains a pointer to the execution context of the global:

enter image description here

In your case, when the setInterval() runs it immediately/synchronously returns the ID and it is set in the timer variable. Since the timer variable is defined in the scope of the countNumbers function the inner/callback function forms a clousure over it. The execution context of the callback can reach and access the timer variable through the scope chain.

Now when you run the setInterval the callback is queued and executed at the specified interval asynchronously. Due to the clousure formed earlier the callback has access to the timer variable declared in the outer function scope, so when the number reaches 10 it can use that value of the ID from the outer function scope to cancel the interval.

Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44
  • Thanks for the precise reply. To enrich the discussion, here is a good explanation of Closure in js. I found it helpful: [Closures in JS](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – BaN Sep 11 '19 at 12:08
  • @Baran Nazari please accept my answer if you found it useful! – Fullstack Guy Sep 11 '19 at 12:12