ES6 Let there be let
In the beginning there was var
And var was a little bit tricky to understand. So, along came es6 with the new shiny let.
Block level scoping
With es6 the introduction of the let keyword introduces block level variable scoping. This allows the declaration and assignment of variables that have block level scope. Now we can see that the first messageInBottle let variable retains its value as the second messageInBottle let variable is restricted to the scope of its code block.
Hoisted by your own petard
In the code below we would expect the output to be the range of numbers 0-9 squared but the output is in fact the number 10 repeated 10 times. This occurs due to the reference of n pointing to the value of n in the loop which has exited when it incremented to the number 10. This variable hoisting moves the declaration of the variable n out of the loop and instead to the top of the function scope.
This can be solved by using a closure which are nested functions that retain a reference to the enviroment in which they were created. The closure retains the value of n that it was passed during its creation. We now see the expected output of the range 0-9 squared.
The newly introduced let keyword can help us gain the expected output by its ability to create a new instance of n each time the code goes through the for loop.