Non funziona perché viene analizzato come a FunctionDeclaratione l'identificatore del nome delle dichiarazioni di funzione è obbligatorio .
Quando lo circondi tra parentesi, viene valutato come un FunctionExpressione le espressioni di funzione possono essere nominate o meno.
La grammatica di un FunctionDeclarationassomiglia a questo:
function Identifier ( FormalParameterListopt ) { FunctionBody }
E FunctionExpression s:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Come puoi vedere l' opzioneIdentifier (Identificatore opt token ) in FunctionExpressionè facoltativo, quindi possiamo avere un'espressione di funzione senza un nome definito:
(function () {
alert(2 + 2);
}());
O espressione di funzione denominata :
(function foo() {
alert(2 + 2);
}());
Le parentesi (formalmente denominate Operatore di raggruppamento ) possono racchiudere solo espressioni e viene valutata un'espressione di funzione.
Le due produzioni grammaticali possono essere ambigue e possono apparire esattamente uguali, ad esempio:
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
Il parser sa se è a FunctionDeclarationo a FunctionExpression, a seconda del contesto in cui appare.
Nell'esempio sopra, il secondo è un'espressione perché l' operatore Comma può anche gestire solo espressioni.
D'altra parte, FunctionDeclarations potrebbe effettivamente apparire solo nel cosiddetto Programcodice " ", che significa codice all'esterno nell'ambito globale e all'interno FunctionBodydelle altre funzioni.
Le funzioni all'interno dei blocchi dovrebbero essere evitate, perché possono condurre un comportamento imprevedibile, ad esempio:
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
Il codice sopra dovrebbe effettivamente produrre un SyntaxError, poiché un Blockpuò contenere solo istruzioni (e la specifica ECMAScript non definisce alcuna istruzione di funzione), ma la maggior parte delle implementazioni sono tolleranti e prenderanno semplicemente la seconda funzione, quella che avvisa'false!' .
Le implementazioni di Mozilla - Rhino, SpiderMonkey - hanno un comportamento diverso. La loro grammatica contiene un'istruzione di funzione non standard , il che significa che la funzione verrà valutata in fase di esecuzione , non al momento dell'analisi, come accade con FunctionDeclarations. In queste implementazioni otterremo la prima funzione definita.
Le funzioni possono essere dichiarate in diversi modi, confrontare quanto segue :
1- Una funzione definita con il costruttore Funzione assegnata alla variabile si moltiplica :
var multiply = new Function("x", "y", "return x * y;");
2- Una dichiarazione di funzione di una funzione chiamata moltiplica :
function multiply(x, y) {
return x * y;
}
3- Un'espressione di funzione assegnata alla variabile si moltiplica :
var multiply = function (x, y) {
return x * y;
};
4- Un'espressione di funzione nominata nome_funzione , assegnata alla variabile moltiplicare :
var multiply = function func_name(x, y) {
return x * y;
};