is the so-called closure 
  I  is fine because  let  is equivalent to 
.
let timeCount = 0;
for (let i = 0; i < 5; iPP) {
    {
        let j = i;// i{}
        setTimeout(() => {
            console.log("i..", j);
            console.log("timeCount..", timeCount);
        }, 1000 * timeCount);
        timeCountPP;
    }
}
 and if you put  I  into the global scope, it will all be 5 
.
let timeCount = 0;
let i = 0;
for (; i < 5; iPP) {
  setTimeout(() => {
    console.log("i..", i);
    console.log("timeCount..", timeCount);
  }, 1000 * timeCount);
  timeCount PP;
}
 let timeCount = 0;
for (let i = 0; i < 5; iPP) {
  setTimeout(() => {
**alert(2)**
    console.log("i..", i);
    console.log("timeCount..", timeCount);
  }, 1000 * timeCount);
**alert(1)**
  timeCount PP;
}
setTimeout0alertsetTimoutsetTimeout,timeCount5
 
 Ah. The Nikkei problem. 
 Please search by yourself: "Block scope" 
 it's very simple. 
 because the  for  loop executes first, and then executes the asynchronous  setTimeout . 
  for  the  timeCount  is 5, and then the printing in  setTimeout  is 5! 
 and I is because the block-level variable  let  
 is used in the loop.
for (let i = 0; i < 5; iPP) {
  setTimeout(() => {
    console.log("i..", i);    // 1234
  }, 100);
}
  1, let binding scope 
 2, you have registered 5 setTimeout, until the execution time timeCount has changed 
 
  js [all asynchronous] callback functions are always executed after the normal code has been executed, even the settimeout delay of 0 milliseconds does not change the nature of the callback function.