let
and var
are not the same.
let
defines a variable in a block scope, such as your for loop.
var
defines a variable in the global or function scope.
So when you get the code:
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
the outside "bar" is defined for the function doBar
while the inner "bar" is defined for the for(){}
block scope.
There is no "redeclaring". When bable converts this, you get the expected behavior, the outside "bar" is within function, when you exit the for loop it remains at the max value, the inside _bar
is an entirely different variable.
Since they are both converted to var
instead of let
and are hoisted.
Comment related example:
If you were to have this type of code:
function doBar(bar) {
for (let bar = 0; bar < 10; bar++) {
let bar = true;
}
}
To begin with this is semantically wrong. This contains a re-declaration. Both of these bar
variables are declared within the scope of the for's block. However you will get no error thrown, and this is the case without babel as well. Since the re-declaration of the variable bar occurs within the for's scope block, the for's "parameter" bar is overridden and inaccessible to the block itself, however it seems that the loop still runs normally, the correct number of times.
Because of this "silent error" and re-declared variable let bar
within the block, babel doesn't see these two variables as the same, they are different to it. The reason for the error lies in the fact that by re-declaring a variable within the block, you effectively make the block's own variable in-accessible to anything, either the block or outside of it.
Now look at it from babel's perspective, the loop should run, the loop's parameter is not accessible anywhere inside or outside of the for's parenthesis, thus this is an isolated "scope" for the bar
within the for.
Unlike let
, var
can be re-declared without raising an error, however this silent re-declaration doesn't raise an error in both cases, where one should have been risen and that is what causes the issue.
The solution is to write a proper code, but you are 100% right, this is not the correct behavior, however, neither is that of the regular javascript interpreter of the non-bable code as it should throw an error, and you cannot expect/blame babel for interpreting wrong code the wrong way.