for 문에 사용한 let은 반복문을 돌 때마다 새로운 블록을 생성합니다. 그리고 블록별로 i 변수의 값이 고정됩니다. 이것도 블록 스코프의 특성이라고 보면 됩니다. 따라서 클로저 내부의 i 변수도 setTimeout() 함수를 호출할 때의 i 변수와 같은 값이 들어갑니다.
• i가 0일 때 블록0 생성, setTimeout(콜백, 1000) 실행, 블록0의 i는 0
• i가 1일 때 블록1 생성, setTimeout(콜백, 2000) 실행, 블록1의 i는 1
• i가 2일 때 블록2 생성, setTimeout(콜백, 3000) 실행, 블록2의 i는 2
• i가 3일 때 블록3 생성, setTimeout(콜백, 4000) 실행, 블록3의 i는 3
• i가 4일 때 4 < numbers.length는 false이므로 반복문이 끝남
• 1초 후 콜백 실행(블록0의 i는 0)
• 2초 후 콜백 실행(블록1의 i는 1)
• 3초 후 콜백 실행(블록2의 i는 2)
• 4초 후 콜백 실행(블록3의 i는 3)