for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
},i * 1000 );
}
Hello, in the following piece of code, the value of i is always 5 , in the console.log(). Why?
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
},i * 1000 );
}
Hello, in the following piece of code, the value of i is always 5 , in the console.log(). Why?
With this example you would see approximately what happens with the function.
The only thing I did was put a
console.log()
outside the functionsetTimeout
and add astring
to the one that exists inside said function to differentiate.If we review what the console spits out at us, we can see that it is first painted:
To later spit:
Having the browser console timer activated also allows us to see when each console output is executed.
Reviewing this we can see that the function
setTimeout
takes longer to launch for the first time than it takes for the loop to go through the entire loop, so when it accesses the variablei
it already has a value of 5.The best way to understand what happens is to reproduce the execution manually:
And a second later, with i equal to 5 (which is when the loop is done), its value is printed.
And a second later, with i equal to 5 (which is when the loop is done), its value is printed.
And a second later, ... well, we already know what happens.
This happens because a function closure has been created: i is an external variable to the anonymous function that has been passed to setTimeout, so it remains in memory with the last existing value.
Why is i shared between the 5 functions? Well, you have to understand that the use of
var
entails a special behavior : The compiler "uploads" the declaration to the beginning of the block:Instead, if you used
let
, in each iteration you would be working with a different instance :Another solution, in case you can't use let (doesn't work in IE10), is to use the following:
The function
setTimeout
allows defining the parameters with which the callback function will be called :To answer you must know two things:
.js
and puts asynchronous functions in its event queue ; that is to say that the code executed in the first instance isfor (var i = 0; i < 5; i++){ }
and in the Javascript event queue it remains five timessetTimeout(function() { console.log('TimeOut: ' + i); },i * 1000 );
var
it has another type of scope. for which the last value will be #5, and when executing thesetTimeout
from the event queue i already has the value #5I will modify the code a little, for practical purposes you can understand why 5
The solution to this question I invite you to read this answer:
By declaring the variable with
var
,for
its value is being overwritten. Try with alet
:You can make a function that returns another function.
This function receives the argument
i
, and it is transferred to the function inside, although that function does not receive any argument.Lastly, the argument for that function to be generated is passed .