Look at the results of for...loop with let , var , setTimeout() function. Last result is not obvious: var has a functional scope, not block one for...loop executes setTimeout() 5 times timeout callbacks are sent into the execution queue and wait when call stack is empty for...loop is finished callbacks are triggered one by one at that time global i variable is 5 all callbacks log 5 into console I expected i = 4 at the end of the for...loop but surprisingly for...loop increments i last time, even though condition i < 5 is not true and it does not fire code in its body bellow can see the prove