Hoisting

In notebook:
FrontEndMasters Advanced JavaScript
Created at:
2016-10-03
Updated:
2016-10-03
Tags:
Fundamentals JavaScript
Hoisting is a mental model, not a JS spec.

variable declaration is done first, when the JS engine reads the code. So
  a;
b;

a = b;
b = 2;
is read by the engine as:
  var a;
var b;

a;
b;

a = b;
b = 2;
Basically line #7 is moved up to line #1. 

This is hoisting, that is variable and function declarations are move to the top when the engine reads the code during compile phase. 
Compile phase is line #1-2.

In the case functions:
  var a = b();
var c = d();

a;
c;

function b() {
  return c;
}

var d = function () {
  return b();
};
function expression doesn't get hoisted (​var d = function...​) only function declaration ( ​function b()​ ). 
So after compiling the code would look like this:
  function b() {
  return c;
}

var a;
var c;
var d;

a = b();
vc = d();

a;
c;

d = function () {
  return b();
};
The above code makes it easier to visualise hoisting. The key knowing how the compiler moves variable declarations to the top.

Functions get hoisted first, before variables. 
  foo(); // "foo"

var foo = 2;

function foo() {
  console.log("bar");
}

function foo() {
  console.log("foo");
}
This is simply how the JS spec is defined. 

Why hoisting? Hoisting and mutual recursion

The key for hoisting is recursion (when the function calls itself). "Mutual recursion" is when 2 or more functions call each others. There are some computer science problems that can only be solved with mutual recursion, because (amongst other) you need to keep track of stacks.

Mutual recursion would be impossible without hoisting. Otherwise one of them would always be declared too late.
​let​ gotcha

the temporal dead zone (​ReferenceError​)
  function foo(bar) {
  if (bar) {
    console.log(baz); // ReferenceError
    let baz = bar;
  }
}

foo("bar");
basically ​let​ don't hoist