И еще вопрос: ждет ли тело функции выполнение setTimeout?
нет.
чтобы цикл ждал на каждой итерации, надо промисифицировать setTimeout, цикл запускать в async-функции, таймер авайтить.
const delay = (ms) => new Promise(r => setTimeout(r, ms));
async function run() {
for (var i = 0; i < 3; i++) {
await delay(1000);
console.log(i);
}
}
run();
и теперь уже без разницы, let или var, думаю понятно почему.