4 ms·
Firefox doesn’t hoist function declarations in blocks
- deleted 15y ago[deleted]
- jmtulloss 15y agothey work, they just don't get hoisted.
- clintjhill 15y agoYes - that's not the point however. It's the "hoisting" that is different within those blocks. Firefox isn't hoisting based indirectly on spec. This can be circumvented by not using function declarations and instead using variable declarations (which I believe do get hoisted in all browsers).
- nxn 15y agoI assume you mean this form: var f = function () {}; ? If so, I don't think that will circumvent the issue since only the variable declaration will be hoisted, the function being assigned will probably not be. You'd end up with 'not a function' like error when invoking instead of undefined. EDIT: Actually, I'm not sure if your last sentence is talking about the problem in the article since the person your reply was to has deleted their post. If it isn't, then disregard.
- azakai 15y agoAs 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 15y agoIt 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 15y agoThe 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 15y agoPlease 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 15y agoI see, thanks for the clarification!
- deleted 15y ago[deleted]
- skimbrel 15y ago>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().