tl;dr it's due to how function expressions and function declarations work (also, function hoisting): https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
More detailed response:
Putting the following console.log's in the code will help you visualize what is happening, and I think answer your question.
var foo = 1;
console.log('0', foo)
function bar() {
console.log('1', foo)
foo = 10;
console.log('2', foo)
return;
console.log('3', foo)
function foo() {}
console.log('4', foo)
}
console.log('5', foo)
bar();
console.log('6', foo)
The output is as follows:
'0' 1
'5' 1
'1' function foo() {}
'2' 10
'6' 1
So to your suspicion, console.log('3',foo) and console.log('4',foo) never get called after the return statement, which was expected. Your question now is probably "Why is my console.log('1',foo) assigned to the function foo() {}", which can be answered with the following SO question which describes function declaration vs. function expressions, i.e.
function foo(){}
vs
var foo = function(){}
Why can I use a function before it's defined in Javascript?
Basically when bar
is executed, the immediate definition of foo
becomes function(){}, but the key concept here is this definition of foo
is local to within the bar()
function, and outside of bar
's scope it is still assigned to 1.
Another good read on function declarations and expressions: https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/