JavaScript supports nested function declarations:
function outer() { function inner() { /* ... */ } // ... }
But according to the standard, nested function declarations are only allowed to appear at the outermost level of their parent function (or script). If you nest a function declaration inside of another statement, you've waded into non-standard territory:
{ // ... function f() { /* ... */ } // this is non-standard JavaScript! // ... }
The function f is a substatement function declaration: it is a function declaration that appears inside a substatement of its parent function, rather than at its parent function's top level. Not only is this non-standard, but different JavaScript engines exhibit different behavior for this kind of code.
This browser exhibits scoping semantics for function declarations that are nested within substatements of their parent function or script.
First of all, you should really care about your code behaving the same across different browsers! Second of all, dynamic scope is widely understood to be a bad thing. It has bad performance, and is harder to use correctly without accidentally introducing strange and subtle bugs. Firefox is the only browser that uses dynamic scoping for substatement function declarations, but Mozilla is considering trying to change this.
In the future, strict mode JavaScript will provide block-local scoping for substatement function declarations. So you should beware of depending on the hoisting of function scope, since migrating code to strict mode could change its behavior.