po co tak kombinować?
for (let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
Skoro w pętli używasz let to nie ma potrzeby bawienia się w starą metodę z IIFE. Let przy każdej iteracji zapamiętuje wewnętrznie wartość końcową, po czym deklaruje zmienną "i" od nowa z jej "poprzednią" wartością. Dzięki temu funkcja wewnątrz for de facto zawsze operuje jakby na "innej" zmiennej.