

Firefox doesn’t hoist function declarations in blocks - Isofarro
http://statichtml.com/2011/spidermonkey-function-hoisting.html

======
azakai
As the article says, what Firefox is doing is the correct behavior. I am
surprised though that all other browsers are doing it wrong, I would have
expected some variation.

Worth checking btw if JS strict mode fixes this. I know it fixes related
issues.

~~~
tolmasky
It isn't, it just has different incorrect behavior. As stated in the article,
function declarations shouldn't be supported as statements at all -- but
FireFox DOES support them, it just doesn't go as far as to hoist them. This
seems like a bad compromise: because it half supports the feature but
surprises you in that it works subtly differently. It probably wasn't a
conscious decision but rather the result of fixing some random compatibility
issue with a site that expected to be able to use functions declarations as
statements but didn't rely on hoisting.

~~~
azakai
The article states that Firefox's behavior is according to the spec. I didn't
read the spec myself, did you do so and see that the article is wrong?

~~~
spjwebster
Please read again. I said:

"Firefox doesn’t actually issue a warning, which would have made my job
tracking this issue down much easier. Moreover, functions declared within a
block before being called work just fine, so it's not that function
declarations can't by used as statements so much as SpiderMonkey won't bother
to hoist them before executing any other code in that block."

As I said, the grammar in the ECMA-262 spec only allows Statements within
Blocks, and a FunctionDeclaration isn't a Statement.

None of the browsers adhere to the spec, but I suspect they're just trying to
play nicely with legacy content. Firefox just happens to play differently to
all the other browsers.

~~~
azakai
I see, thanks for the clarification!

------
skimbrel
>The grammar reference section states that the only constructs allowed within
a Block are Statement constructs, and that a FunctionDeclaration isn’t a
Statement.

Huh! Never knew that. I wonder what their reasoning was when they decided
that. Behavior in this case is all over the map in other languages: C and
Python both consider function declarations and definitions as statements, but
C allows you to provide a forward declaration of a function that you define
later, after invoking the function, while Python doesn't. Perl allows forward
references to subroutines without a preemptive declaration; Java considers
method declarations as separate grammatical entities from statements but
doesn't care what order you put them in within a class; Ruby behaves similarly
to Perl.

PHP (as always) is a total odd-man-out: it considers a function declaration to
be a statement, doesn't allow forward references to functions, and it exposes
nested function definitions to the current namespace as soon as the parent
function has been executed once. That is, if you define a function foo() and
inside its body define bar(), you can access bar() from outside of foo(), but
only once you have invoked foo().

