After reading a few links as here and here and here I'm having trouble to understand why Ver2 prints out 5 5 5 5, rather than 1 2 3 4
Ver1
for (var i = 1; i < 5; i++) {
    setTimeout(() => console.log(i), 1000)  // 5 5 5 5
}
Ver2
for (var i = 1; i < 5; i++) {
    setTimeout(() => console.log(i), 0)  // 5 5 5 5
}
Ver3
for (let i = 1; i < 5; i++) {
    setTimeout(() => console.log(i), 1000)  // 1 2 3 4 
}
In Ver3, since let is block scoped. 
- i = 1, setTimeout(() => console.log(1), 1000) event is queued
- i = 2, setTimeout(() => console.log(2), 1000) event is queued
- i = 3, setTimeout(() => console.log(3), 1000) event is queued
- i = 4, setTimeout(() => console.log(4), 1000) event is queued Hence, it prints out 1 2 3 4 in sequence.
In Ver2, since var is function scoped. 
- i = 1, setTimeout(() => console.log(i), 0) event is queued (Since delay is 0, shouldn't this print out 1 immediately?
- i = 2, setTimeout(() => console.log(i), 0) event is queued (prints out 2 immediately)
- i = 3, setTimeout(() => console.log(i), 0) event is queued (prints out 3 immediately)
- i = 4, setTimeout(() => console.log(i), 0) event is queued (prints out4 immediately)
- i = 5
After testing this out a couple of times, results consistently output 5 5 5 5 why is this the case? 
0ms   Start
1ms   i = 1, queued console.log(i) after 0ms(1) (Since this is executed immediately, it should print 1??)
2ms   i = 2, queued console.log(i) after 0ms(2)
3ms   i = 3, queued console.log(i) after 0ms(3)
4ms   i = 4, queued console.log(i) after 0ms(4)
5ms   i = 5
In Ver1, since var is function scoped
- i = 1, setTimeout(() => console.log(i), 1000) event is queued, wait for 1000ms
- i = 2, setTimeout(() => console.log(i), 1000) event is queued, wait for 1000ms
- i = 3, setTimeout(() => console.log(i), 1000) event is queued, wait for 1000ms
- i = 4, setTimeout(() => console.log(i), 1000) event is queued, wait for 1000ms
- i = 5
After ~1000ms(or slightly over due to 4 queuing time), console should log 5 5 5 5.
0ms   Start
1ms   i = 1, queued console.log(i) after 1000ms(1)
2ms   i = 2, queued console.log(i) after 1000ms(2)
3ms   i = 3, queued console.log(i) after 1000ms(3)
4ms   i = 4, queued console.log(i) after 1000ms(4)
5ms   i = 5
1000ms console.log(i) when i = 5(1)
1001ms console.log(i) when i = 5(2)
1002ms console.log(i) when i = 5(3)
1003ms console.log(i) when i = 5(4)
