In this code, The function function () { console.log(i);}
, I want to know where this function had been created.
This function is defined as a function expression. Such an expression is evaluated at runtime, much like an expression { y: x*x }
would be evaluated at runtime. But in this case the evaluation result is a function object. And that function is then passed as argument to setTimeout
. This means there are just as many functions created as there are iterations of your for
loop.
Now, even though the function expression is evaluated at the moment setTimeout
is executed, this does not mean that the body of the function is executed at that same time. It is not. It will only be executed when the timeout expires. At that time the function body executes, and at that time only it will evaluate expressions used in that code, such as variable i
. In your example, the variable i
will already have reached the value howMany+1
, because that for
loop already ran to completion before the timer expired, and the callback got called.
If that is something you want to avoid, then use a separate variable i
for each iteration of the for
loop. With let
instead of var
you create such distinct variables, which only live inside the for
loop's block. And so then each of the function expressions will reference its "own" i
:
function countSeconds(howMany) {
for (let i =1; i <= howMany; i++) {
setTimeout(function () {
console.log(i);
}, i * 1000 );
}
};
countSeconds(10);