setTimeout is a browser API method, but how does it access i? i is
declared inside the for loop, and I am accessing i inside the method
setTimeout even though i is not passed through, how?
In javascript, nested functions can access higher order variables and functions.
//global context - any variable declared here will be availabe within any nested function
var someVariable = 0;
var someSecondVariable = 1;
const someFunc = () => {
//someVariable and someSecondVariable are accessible here
console.log("someFunc", someVariable, someSecondVariable);
var someThirdVariable = 2;
for(let i = 0; i < 5; i++){
const temp = i;
//all higher order variables are still accessible
setTimeout(()=>{
//all higher order variableds are still accessible
console.log("settimeout", i, temp);
}, 4000);
}
}
const someFunc2 = () => {
//cant access someThirdVariable
try {
console.log("someFunc2", someThirdVariable);
}catch(e){
console.warn(e.message);
}
}
someFunc();
someFunc2();
Why is 2,2 printed, instead of 0,1?
setTimeout is an asynchrounous method and doesn't get called right away. The loop ends before the first timeout is event started. This means, that at the time the setTimeout callback is called i is already equal to 2.
- i = 0 -> continue looping
- i = 1 -> continue looping
- i = 2 -> stop looping because 2 < 2 = false
then your setTimeout callbacks are called
console.log(i) //where i = 2
console.log(i) //where i = 2
Here you can have 0,1
for (var i = 0; i < 2; i++){
//temp won't get increased in the next iteration
const temp = i;
setTimeout(() => console.log(temp));
}
Compared to php, for example, this is different, we have to specifically tell it to use a higher order variable to be able to access it within the scope of the function.
<?php
$i = 0;
$func = function() use ($i){
echo $i;
};
$func();