A very popular JavaScript interview question on Lexical scope and closure is like the follow.

for (var i = 1; i < 6; i += 1) {
    //(function (i) {
 setTimeout(function() {
          console.log("I've waited " + i + " seconds!");
     }, 1000 * i);
    //})(i);
}

The code has a bug, that all the log output is the same, like the following.

Previously, to solve that is to uncommon the lines in previous code, because we can close the variable "i" in lexical scope using function. So that you can have something like

Now we have ES2016 or ES6, the new solution is actually very simple, just change "var" to "let". This is because let support block scope. In the loop block, the variable "let i" is private to the block. Every loop an new private scope is created. If you use transpiler such as typescript or babel, you can make it works in browser like IE10 or below and Safari 9. The transpilers are actually pretty smart, the following is transpiled by typescript, pretty impressive.