The same reason why any strict operator appears in any programming language - to limit the number of ways you can shoot yourself in the foot. Old-school Javascript is just chock full of those.
Note that you can use let
for a block-local scope:
while (i < 5)
{
let a = 42;
i++;
}
Even though the loop runs a couple of times, a
is always initialized properly.
Now, what would happen if you have another variable in the higher scope?
let a = 42;
while (i < 5)
{
let a = 10;
// What is the value of a here?
i++;
}
// And here?
There's a certain level of ambiguity here - and ambiguity is a bad feature in a programming language. This isn't a problem with the non-block-scoped var
- that one has tons of its own issues, and people misuse it all the time, but at least its obvious that var
is never block-scoped. And even then - people do use it as if it were block-scoped.
The only way to fix this insanity is to make the language a bit stricter. Did this actually mean you lost any feature whatsoever? No. Variable shadowing was a bad idea with var
, and it would still be a bad idea with let
(and as my example shows, possibly worse).
This isn't unique to Javascript, not by a long shot. For example, in C#:
int i = 0;
int i = 42; // Compiler error: A local variable named 'i' is already defined in this scope
Why? Because you've obviously made a mistake. Perhaps you copied a piece of code from somewhere else, and didn't notice you already have another variable named i
declared. Perhaps you forgot you're in the middle of another loop, that also uses i
as a loop variable. There's no real legitimate use, and yet there's tons of failure modes - that's simply a terrible language feature. The simple compiler error prevents almost all of those failures from happening - and many of those failures can be very hard to find, especially if the "inner" block isn't used too often.