Потому что все функции, переданные в setTimeout, вызываются после того, как цикл будет выполнен - а значение i к этому моменту будет равно 10.
Как исправить? Есть варианты:
for (var i = 0; i < 10; i++) {
setTimeout(function() {
alert(+this);
}.bind(i), 100);
}
for (let i = 0; i < 10; i++) {
setTimeout(function() {
alert(i);
}, 100);
}
for (var i = 0; i < 10; i++) {
setTimeout(alert, 100, i);
}
for (var i = 0; i < 10; i++) {
setTimeout(new Function(`alert(${i})`), 100);
}
for (var i = 0; i < 10; i++) {
setTimeout(function() {
alert(i++);
}, 100);
}
i = 0;