I’m on this page discussing the while and for loops:
<!DOCTYPE html>
<script>
"use strict";
let i = 0;
for (i = 0; i < 3; i++) { // use an existing variable
alert(i); // 0, 1, 2
}
alert(i); // 3, visible, because declared outside of the loop
</script>
I don’t understand why the final alert(i) shows 3, since it is outside the curly braces. Isn’t it the same as being outside a function?
@WebSteve notice for (i = 0; is not for (let i = 0. It’s using the ‘i’ declared outside of the loop.
A similar example with a function
let i = 0
// The function doesn't have a locally declared 'i' so looks up the
// scope chain to the globally declared one above.
function increment() {
i = 0;
i += 3;
}
increment()
alert(i) // 3
And a function with a locally declared variable
let i = 0
function increment() {
let i = 0;
i += 3;
}
increment()
alert(i) // 0
So in this one, we are declaring the variable.
Then we call the function at increment().
Then the function cycles through and when done, we jump out of the function.
Then the alert(i) returns the result.
Here’s what I don’t understand. Since JS is run from top to bottom, why doesn’t the position of increment() immediately after the function cause the script to form an endless loop? Why does function increment() execute and then jump the increment() call and go right to the alert?
The only thing I can think of is that the function is happening in the place of the call to the function.
You can think of the increment function as being a separate script that before execution is set aside. I have illustrated that with the global object. You can also see it has an i, which is yet to be initialised (no value). This process is referred to as hoisting.
Thread of execution
i is given a value of 0
The function increment is invoked.
The function increment had no i of it’s own, sources it via the scope chain finding it in the global object, and again sets it’s value to 0
step 3 is repeated, but this time i is increased by 3
The function increment returns.
The alert function is invoked passing in the value of i
The breakdown I gave above is incorrect and it’s been bugging me. Specifically with regards let declaring a variable on the global object. Had it been var that would have been the case, but not with let or const.
var x = 5;
let y = 10;
console.log(window.x) // 5
console.log(window.y) // undefined
Instead of me trying to interpret the official ECMAScript docs into plain English, for those interested here is a more manageable read.