0

Suppose we have a simple print statement within a for loop such as

for (var i = 0; i < 2; i++){
    setTimeout(() => console.log(i));
}

Two questions.

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?

Why is 2,2 printed, instead of 0,1?

J.Doe
  • 21
  • 3

1 Answers1

2

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.

  1. i = 0 -> continue looping
  2. i = 1 -> continue looping
  3. 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 , 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();
kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131
  • ohkk, so in your example you have method `first`, and `nested1`. Translating that to my example, is `first` method the equivalent to the `for loop` declaration? Do `for loop` and `method` declaration have a relationship? – J.Doe Sep 01 '18 at 12:26