NANCY
NANCY

Reputation: 61

Explain output for closure in Javascript

in following code snippet,6 gets printed 5 times. Kindly explain this output behavior.

as for every i, i am calling settimeout function, so console.log should have that value of i. Code :

for(var i = 1;i <= 5;i++) {
   setTimeout(function() {
      console.log("i:" +  i);
   },i*1000);
}

O/P 6 6 6 6 6

O/P intended 1 2 3 4 5

Upvotes: 0

Views: 42

Answers (4)

Vinod Louis
Vinod Louis

Reputation: 4876

Even a timeout 0 will yield the same result, To understand this you have to understand the concept of callback in terms of event loop. Ideally a callback is executed only when the stack is empty the js code execution is stack based I mean the execution context so when you here say a for loop it means 1st i is pushed into stack so now stack handles the variable and its increment value when it comes to callback (setTimeout) it stores is as an event loop.

the only way the to run the block inside event-loop is when your stack is empty i.e when your loop ends as as its an closure function it retains the last value where all logs are printed.

See the example you will see 1 to 6 outer to callback as it gets executed in stack but callbacks only when your stack is empty.

If you want to best understand the execution context then go to loupe and copy paste your js code to see the action.

for(var i = 1;i <= 5;i++)
    {
        console.log(i)
        setTimeout(function(){
                console.log("i:" +  i);
                     },0
               );

    }

Upvotes: 2

alebianco
alebianco

Reputation: 2555

that's because the function uses the variables in the same scope of the for loop

by the time the setTimeout function is executed, the variable i in the scope has changed value, so all timers will print the last value of the loop

try passing the i value as an argument of setTimeout, so that it's evaluated immediately and the function can use a value in it's own scope, with no side effects playing tricks

for(var i = 1;i <= 5;i++)
    {
        setTimeout(function(a){
                console.log("i:" +  a);
                     },i*1000,i
               );

    }

Upvotes: 1

Balaji V
Balaji V

Reputation: 956

Since setTimeout is asynchronous , the for loop would have run before the sitetimeOut function is called . The last iteration of the for loop loop sets i to 6 . Hence once the set timeOut function runs after the for loop it will print out 6 .

Upvotes: 0

Vaibhav Kumar
Vaibhav Kumar

Reputation: 544

In js, variables have block/function scope and also setTimeout work asynchronously.

Upvotes: 0

Related Questions