Hoisting is a handy shorthand, but declarations are not literally moved. JavaScript registers identifiers in lexical environments before executing code. section 5.5.3
Watch what happens when code runs:
- A function declaration can be accessed before its position in the code; a function expression or arrow function cannot. section 5.5.3
- A var declaration is registered, but its later assignment still runs during execution and can replace a function value. section 5.5.3
Listing 5.9. Accessing a function before its declaration
assert(typeof fun === "function",
"fun is a function even though its definition isn't reached yet!"); #A
assert(typeof myFunExp === "undefined", #B
"But we cannot access function expressions"); #B
#B
assert(typeof myArrow === "undefined", #B
"Nor arrow functions"); #B
function fun(){} #C
var myFunExpr = function(){}; #D
var myArrow = (x) => x; #D
Compare access before a function declaration with access before function expressions and arrow functions. section 5.5.3

