Javascript Function Declarations vs. Function Expressions

Function Declarations vs. Function Expressions

Question 1:

function foo(){
function bar() {
return 3;
}
return bar();
function bar() {
return 8;
}
}

console.log(foo()); // 8

Question 1 uses function declarations which means they get hoisted.

“Function declarations and function variables are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter.”

When a function declaration is hoisted the entire function body is lifted with it, so after the interpreter has finished with the code in Question 1 it runs more like this:

//**Simulated processing sequence for Question 1**
function foo(){
//define bar once
function bar() {
return 3;
}
//redefine it
function bar() {
return 8;
}
//return its invocation
return bar(); //8
}
alert(foo());

Question 2

function foo(){
var bar = function() {
return 3;
};
return bar();
var bar = function() {
return 8;
};
}
alert(foo());

Do Function Expressions get Hoisted too?

That depends on the expression.

var bar = function() {
return 3;
};

The left hand side (var bar) is a Variable Declaration. Variable Declarations get hoisted but their Assignment Expressions don’t. So when bar is hoisted the interpreter initially sets var bar = undefined. The function definition itself is not hoisted.

Thus the code in Question 2 runs in a more intuitive sequence:

//**Simulated processing sequence for Question 2**
function foo(){
//a declaration for each function expression
var bar = undefined;
var bar = undefined;
//first Function Expression is executed
bar = function() {
return 3;
};
// Function created by first Function Expression is invoked
return bar();
// second Function Expression unreachable
}
console.log(foo()); //3

Question 3

console.log(foo());
function foo(){
var bar = function() {
return 3;
};
return bar();
var bar = function() {
return 8;
};
}
function foo(){
//a declaration for each function expression
var bar = undefined;
var bar = undefined;
//first Function Expression is executed
bar = function() {
return 3;
};
// Function created by first Function Expression is invoked
return bar();
// second Function Expression unreachable
}
alert(foo());

Question 4

function foo(){
return bar();
var bar = function() {
return 3;
};
var bar = function() {
return 8;
};
}
alert(foo());
//**Simulated processing sequence for Question 4**
function foo(){
//a declaration for each function expression
var bar = undefined;
var bar = undefined;
return bar(); //TypeError: "bar not defined"
//neither Function Expression is reached
}
alert(foo());