I just ran into a problem when defining a function in a block scope. Consider the following program:
try {
greet();
function greet() {
alert("Merry Christmas!");
}
} catch (error) {
alert(error);
}
I expected this program to alert Merry Christmas!
. However in Firefox is gives me the following ReferenceError
:
ReferenceError: greet is not defined
On Opera and Chrome it alerts the greeting as I expected it to.
Evidently Firefox treats the function inside the block scope as a FunctionExpression
while Opera and Chrome treat it as a FunctionDeclaration
.
My question is why does Firefox behave differently? Which implementation is more logical? Which one is standards compliant?
I understand that declarations in JavaScript are hoisted and so if the same function is declared in two or more different blocks in the same scope then there'll be a name conflict.
However wouldn't it be more logical to redeclare the function every time it's declared so that you can do something like this:
greet(); // Merry Christmas!
function greet() {
alert("Merry Christmas!");
}
greet(); // Happy New Year!
function greet() {
alert("Happy New Year!");
}
I think this would be very useful, in addition to solving the block scoping problem I described above.
Actually, function declarations inside block scopes is expressly not standardized and the behavior is implementation dependent. Different implementation respond differently. You'd get the same weirdness if you tried to declare a function inside an if statement.
The ES5 spec recommends that implementers make function declarations inside blocks be marked as a warning or error.