liveBook · Manning

Hoisting

As explained in Get Programming with JavaScript Next: New features of ECMAScript 2015, 2016, and beyond

The behavior by which declarations are processed as though moved to the top of their scope before execution, affecting when bindings can be accessed.

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

How Get Programming with JavaScript Next: New features of ECMAScript 2015, 2016, and beyond covers it

How deep it goes
Works through shadowing and temporal-dead-zone behavior, but does not delve into language implementation internals.
Examples
Uses shadowed `myData`, an early `let` read, and `var` versus `let` loop examples.
What you can do after
Understand when `let` and `var` bindings are in scope and what happens when code reads them early.
How it connects
Connects hoisting to block scope, function scope, `let`, `var`, and the temporal dead zone.

Also explained in

Compare how 2 books explain hoisting →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Get Programming with JavaScript Next: New features of ECMAScript 2015, 2016, and beyond. The section links point to the parts of the book it draws on.