Why can a variable affect code before its declaration? Hoisting means a declaration’s binding is in scope before the declaration line. The behavior differs: an early read of `let` throws a reference error, while an early read of `var` produces `undefined`. section 4.2
// ------ scope of outer myData starts here -----
let myData = getDefaultData();
if (condition) {
// ------ scope of inner myData starts here -----
doSomePrework(myData); // <-- What variable is this???
//... more code
let myData = getData();
//... more code
doSomePostwork();
// ------ scope of inner myData ends here -----
}
// ------ scope of outer myData ends here -----
The inner `myData` binding shadows the outer one throughout the `if` block. The early read encounters that inner binding before its declaration, so it is in the temporal dead zone and throws rather than using the outer value. section 4.2
Keep these scope and access rules distinct:
- `let` is scoped to its block; `var` is scoped to its function. Each binding is in scope before its declaration, but an early `let` read throws while an early `var` read yields `undefined`. section 4.2
- Avoid using a variable before its declaration, and do not replace every `var` with `let` blindly; a blanket change can introduce errors. section 4.3

