It all boils down to hoisting differences :
Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter. Function parameters and language-defined names are, obviously, already there. This means that code like this:
function foo() {
bar();
var x = 1;
}
is actually interpreted like this:
function foo() {
var x;
bar();
x = 1;
}
Consider this example :
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
this code is equivalent to :
function test() {
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
}
test();
Look what happened to the function declaration : it is hoisted.
Leet's look at simplier sample : http://jsbin.com/UKICENE/4/edit
console.log(typeof(sayHey));
if(true) {
function sayHey() {
console.log("Hey, inside if");
};}
sayHey();
This will yield function in chrome.
But it will yield undefined in FF.
Hoeever - deferring the calculationm via setTimeout will yield the same result as chrome :
console.log(typeof(sayHey));//undefined
setTimeout(function (){console.log(typeof(sayHey));},1000); //function
if(true) {
function sayHey() {
console.log("Hey, inside if");
};}
sayHey();
So , like Šime said , it delay the evaluation.
If you ask me , I think chrome is doing the right thing
ifstatements. More info is available here: kangax.github.io/nfe/#function-statementsifstatements is non-standard, browsers can implement it anyhow they like, hence the differences.