No funciona porque se analiza como a FunctionDeclaration, y el identificador de nombre de las declaraciones de funciones es obligatorio .
Cuando lo rodea con paréntesis, se evalúa como a FunctionExpression, y las expresiones de función pueden nombrarse o no.
La gramática de un se FunctionDeclarationve así:
function Identifier ( FormalParameterListopt ) { FunctionBody }
Y FunctionExpressions:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Como se puede ver el Identifier(Identificador opt ) token en FunctionExpressiones opcional, por lo tanto, podemos tener una expresión de función sin un nombre definido:
(function () {
alert(2 + 2);
}());
O expresión de función con nombre :
(function foo() {
alert(2 + 2);
}());
Los paréntesis (formalmente llamados Operador de agrupamiento ) pueden rodear solo expresiones, y se evalúa una expresión de función.
Las dos producciones gramaticales pueden ser ambiguas y pueden verse exactamente iguales, por ejemplo:
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
El analizador sabe si es a FunctionDeclarationo a FunctionExpression, según el contexto en el que aparece.
En el ejemplo anterior, el segundo es una expresión porque el operador de coma también puede manejar solo expresiones.
Por otro lado, FunctionDeclarations en realidad podría aparecer solo en lo que se llama " Program" código, que significa código fuera del alcance global y dentro FunctionBodyde otras funciones.
Deben evitarse las funciones dentro de los bloques, ya que pueden conducir a un comportamiento impredecible, por ejemplo:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
El código anterior en realidad debería producir un SyntaxError, ya que un Blocksolo puede contener declaraciones (y la Especificación ECMAScript no define ninguna declaración de función), pero la mayoría de las implementaciones son tolerantes, y simplemente tomarán la segunda función, la que alerta 'false!'.
Las implementaciones de Mozilla -Rhino, SpiderMonkey, - tienen un comportamiento diferente. Su gramática contiene una declaración de función no estándar , lo que significa que la función se evaluará en tiempo de ejecución , no en tiempo de análisis, como sucede con FunctionDeclarations. En esas implementaciones obtendremos la primera función definida.
Las funciones se pueden declarar de diferentes maneras, compare lo siguiente :
1- Una función definida con el constructor Función asignado a la variable multiplicar :
var multiply = new Function("x", "y", "return x * y;");
2- Una declaración de función de una función llamada multiplicar :
function multiply(x, y) {
return x * y;
}
3- Una expresión de función asignada a la variable multiplica :
var multiply = function (x, y) {
return x * y;
};
4- Una expresión de función con nombre func_name , asignada a la variable multiplica :
var multiply = function func_name(x, y) {
return x * y;
};