Why are function declarations handled differently in different browsers?

Although I couldn't find a reference to this easily in google, I'm familiar with the fact that, in javascript, global function declarations get interpreted before any code is executed. In other words, this works fine:

f();
function f() {}

However, I've noticed that chrome and firefox have different interpretations of what a global function declaration is. In particular, chrome is happy reading a function declaration that is inside an if block in the first pass, but firefox is not.

try {document.write(f);}               // works in chrome
catch(e) {document.write(e.message);}  // throws an error in firefox

try {document.write(g);}               // works in chrome and firefox
catch(e) {document.write(e.message);}

if(true) function f() {}
function g() {}

You can try this example yourself with this fiddle. I'm using Chrome 16.0.912.75 and Firefox 9.0.1.

What is the ECMA standard for this behavior? Is there a term for this process of "lifting" function declarations above other code? Is what code gets "lifted" open to interpretation (are both browsers right)? Or is it a bug in one of them?


Solution 1:

Function declarations are not valid in blocks. You have undefined behaviour which is undefined.

Function declarations at a top level (either global or top level within a function) are hoisted.

Function declarations inside blocks are a syntax error in strict mode

(function () { 
  "use strict"; 
  if (true) { 
    function g() { } 
  } 
})();

SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.