Первое что нужно понять, таймер работает асинхронно, а значит будет выполнен после цикла.
Второе - let имеет блочную область видимости (переменная видна в том блоке, где была объявлена, при этом первый операнд for считается тем же блоком, что и тело цикла)
Третье - циклы создают новый скоуп на каждую итерацию (на каждой итерации будет свой let i, при условии что этот оператор внутри цикла)
Ну и еще, в Ваших примерах 1000 относится не к таймауту, это просто бесполезная операция, а таймаут получит значение по умолчанию - 0, думаю это не совсем то, что Вы ожидаете.
Еще один важный момент, функциональное выражение (а стрелочная функция - это тоже функциональное выражение) внутри цикла будет создавать по функции на каждой итерации цикла. Это очень плохо и по памяти и по производительности (такие функции еще и компилироваться и оптимизироваться будут раздельно). И если в случае с let внутри цикла функции хотя бы будут отличаться замыканием (каждая замкнет свою i), то в первом случае будет 5 абсолютно идентичных функций.
Тут можно очень хорошо показать себя, если помимо объяснения принципов работы вспомнить, что setTimeout умеет передавать аргументы в свой колбэк:
const f = i => {
console.log(i);
};
for (let i = 0; i < 5; i++) {
setTimeout(f, 1000, i);
}