Hoisting

  • 14.1 var declarations get hoisted to the top of their closest enclosing function scope, their assignment does not. const and let declarations are blessed with a new concept called Temporal Dead Zones (TDZ). It’s important to know why typeof is no longer safe.

    1. // we know this wouldn’t work (assuming there
    2. // is no notDefined global variable)
    3. function example() {
    4. console.log(notDefined); // => throws a ReferenceError
    5. }
    6. // creating a variable declaration after you
    7. // reference the variable will work due to
    8. // variable hoisting. Note: the assignment
    9. // value of `true` is not hoisted.
    10. function example() {
    11. console.log(declaredButNotAssigned); // => undefined
    12. var declaredButNotAssigned = true;
    13. }
    14. // the interpreter is hoisting the variable
    15. // declaration to the top of the scope,
    16. // which means our example could be rewritten as:
    17. function example() {
    18. let declaredButNotAssigned;
    19. console.log(declaredButNotAssigned); // => undefined
    20. declaredButNotAssigned = true;
    21. }
    22. // using const and let
    23. function example() {
    24. console.log(declaredButNotAssigned); // => throws a ReferenceError
    25. console.log(typeof declaredButNotAssigned); // => throws a ReferenceError
    26. const declaredButNotAssigned = true;
    27. }

  • 14.2 Anonymous function expressions hoist their variable name, but not the function assignment.

    1. function example() {
    2. console.log(anonymous); // => undefined
    3. anonymous(); // => TypeError anonymous is not a function
    4. var anonymous = function () {
    5. console.log('anonymous function expression');
    6. };
    7. }

  • 14.3 Named function expressions hoist the variable name, not the function name or the function body.

    1. function example() {
    2. console.log(named); // => undefined
    3. named(); // => TypeError named is not a function
    4. superPower(); // => ReferenceError superPower is not defined
    5. var named = function superPower() {
    6. console.log('Flying');
    7. };
    8. }
    9. // the same is true when the function name
    10. // is the same as the variable name.
    11. function example() {
    12. console.log(named); // => undefined
    13. named(); // => TypeError named is not a function
    14. var named = function named() {
    15. console.log('named');
    16. };
    17. }

  • 14.4 Function declarations hoist their name and the function body.

    1. function example() {
    2. superPower(); // => Flying
    3. function superPower() {
    4. console.log('Flying');
    5. }
    6. }
  • For more information refer to JavaScript Scoping & Hoisting by Ben Cherry.