цикл пробегается раньше чем отрабатывает timeout
/* написаное ниже - ошибочно */
JS однопоточен, поэтому setTimeout фактически выбрасывает код в конец текущего обработчика, когда i == 10
/* написаное выше - ошибочно */
можно прибегнуть к ES6 и использовать оператор let
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i); // ?
}, 0);
}
таким образом мы сократили область видимости переменной i до блока внутри цикла
а в случае с var переменная была общая и setTimeout выводил только ее конечное значение
UPD: дока для ознакомления тут
https://learn.javascript.ru/let-const
UPD2: По поводу однопоточности я ошибся (в том что это причина).
Исправляюсь )) как оказалось. setTimeout(func,0) и setTimeout(func,4) выполнятся одновременно.
По крайней мере в хроме. минимальный порог значения таймаута в разных браузерах может отличаться, но он больше 0мс. В хром это 4мс. обусловлено это тем, что многие используют setTimeout для асинхронности и страница где несколько setTimeout(func,0) сильно нагрузит процессор. По крайней мере базовой причиной появляения минимальной задержки называют это.