The console will log undefined.
The declaration (but not the assignment) of temp gets hoisted to the top of foo(). So our code gets interpreted as though it were:
So we have a new variable temp inside of foo() that is initialized to undefined, which is what it holds when we hit our log statement.
var a =2;
Encountering var a, Compiler asks Scope to see if a variable a already exists for that particular scope collection. If so, Compiler ignores this declaration and moves on. Otherwise, Compiler asks Scope to declare a new variable called a for that scope collection. Compiler then produces code for Engine to later execute, to handle the a = 2 assignment. The code Engine runs will first ask Scope if there is a variable called a accessible in the current scope collection. If so, Engine uses that variable. If not, Engine looks elsewhere as per scope hirerachy. If Engine eventually finds a variable, it assigns the value 2 to it. If not, Engine will raise its hand and yell out an error.
To summarize: two distinct actions are taken for a variable assignment: First, Compiler declares a variable (if not previously declared) in the
current Scope, and second, when executing, Engine looks up the variable in Scope and assigns to it, if found.