Reputation: 65
This has always been a lingering question for me: If block scopes are created when a let
or const
identifier is enclosed within curly brackets, then how is the let
identifier in the initialization statement of a for
loop not available in the enclosing scope but is instead available inside the curly brackets of the for
loop?
(function() {
for (let i = 0; i < 5; i++) {
console.log(i) // logs current value of i
}
console.log(i) // referenceError
})()
Upvotes: 4
Views: 137
Reputation: 1618
If you don't want to change your syntax, you could use var
.
(function() {
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);
// this should work.
})()
Otherwise, a variable declared with let
or const
has what's called Block Scope meaning that it's only visible inside the curly braces it was defined in. That's essentially the fundamental difference between let
and var
. A variable declared with var
has Function Scope (It's visible throughout the function, even before it's lexical definition, it's value will just be undefined
)
(function() {
console.log(i); // undefined
var i = 10;
console.log(i); // 10
})();
But the example above will only work if there is no "use strict"
anywhere.
Upvotes: 0
Reputation: 370759
That's just how things work. A variable declared at the top of a for
loop like that is only visible inside the current iteration's for
block. You can think of it a bit like this:
<loop> {
let i = getCount();
console.log(i) // logs current value of i
}
where getCount
runs the logic that increments i
.
Variables declared with let
are block-scoped - it wouldn't make sense for i
to be referenceable outside. If the i
was visible outside of the for
, what would you expect its value to be? You already have a separate i
binding for every iteration of the loop. It wouldn't make sense to somewhat-arbitrarily pick one of those bindings to be visible outside.
Upvotes: 2
Reputation: 44107
Because it's a local variable in the for
loop and not outside it. If you had declared it outside the loop, you could access it correctly.
(function() {
let i;
for (i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);
})();
Upvotes: 0