Cela ne fonctionne pas parce qu'il est analysé en tant que FunctionDeclaration
et l'identificateur de nom des déclarations de fonctions est obligatoire .
Lorsque vous l'entourez de parenthèses, il est évalué comme un FunctionExpression
et les expressions de fonctions peuvent être nommées ou non.
La grammaire d'un FunctionDeclaration
ressemble à ça :
function Identifier ( FormalParameterListopt ) { FunctionBody }
Et FunctionExpression
s :
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
Comme vous pouvez le constater, le Identifier
(Identifiant opt ) dans FunctionExpression
est facultatif, on peut donc avoir une expression de fonction sans qu'un nom soit défini :
(function () {
alert(2 + 2);
}());
Ou nommé l'expression de la fonction :
(function foo() {
alert(2 + 2);
}());
Les Parenthèses (formellement appelées l'opérateur de regroupement ) ne peuvent entourer que des expressions, et une expression de fonction est évaluée.
Les deux productions grammaticales peuvent être ambiguës, et elles peuvent avoir exactement la même apparence, par exemple :
function foo () {} // FunctionDeclaration
0,function foo () {} // FunctionExpression
Le parseur sait si c'est un FunctionDeclaration
ou un FunctionExpression
en fonction de la contexte où il apparaît.
Dans l'exemple ci-dessus, le second est une expression car le fichier Opérateur de virgule peut également ne traiter que des expressions.
D'un autre côté, FunctionDeclaration
pourraient en fait n'apparaître que dans ce que l'on appelle les " Program
", c'est-à-dire le code situé à l'extérieur dans la portée globale, et à l'intérieur de la portée de l'utilisateur. FunctionBody
d'autres fonctions.
Les fonctions à l'intérieur des blocs doivent être évitées, car elles peuvent entraîner un comportement imprévisible, par exemple :
if (true) {
function foo() {
alert('true');
}
} else {
function foo() {
alert('false!');
}
}
foo(); // true? false? why?
Le code ci-dessus devrait en fait produire un SyntaxError
puisque a Block
ne peut contenir que des déclarations (et la spécification ECMAScript ne définit aucune déclaration de fonction), mais la plupart des implémentations sont tolérantes, et prendront simplement la deuxième fonction, celle qui alerte 'false!'
.
Les implémentations Mozilla -Rhino, SpiderMonkey,- ont un comportement différent. Leur grammaire contient un hors normes Déclaration de fonction, ce qui signifie que la fonction sera évaluée à temps d'exécution et non pas au moment de l'analyse syntaxique, comme c'est le cas avec le système FunctionDeclaration
s. Dans ces implémentations, nous obtiendrons la première fonction définie.
Les fonctions peuvent être déclarées de différentes manières, comparez les éléments suivants :
1- Une fonction définie avec le Fonction assigné à la variable multiplier :
var multiply = new Function("x", "y", "return x * y;");
2- Une déclaration de fonction d'une fonction nommée multiplier :
function multiply(x, y) {
return x * y;
}
3- Une expression de fonction affectée à la variable multiplier :
var multiply = function (x, y) {
return x * y;
};
4- Une expression de fonction nommée nom_func affecté à la variable multiplier :
var multiply = function func_name(x, y) {
return x * y;
};
44 votes
Je pense que toutes ces notations variées et ces façons de définir/établir/appeler les fonctions sont la partie la plus déroutante du travail initial avec javascript. Les gens ont tendance à ne pas en parler non plus. Ce n'est pas un point sur lequel on insiste dans les guides ou les blogs. Cela m'étonne parce que c'est quelque chose de déroutant pour la plupart des gens, et les personnes qui parlent couramment le js doivent être passées par là aussi. C'est comme une réalité taboue et vide dont on ne parle jamais.
1 votes
Lisez également ce qui concerne le objectif de cette construction ou vérifier un ( technique ) explication (également aquí ). Pour le placement de la parenthèse, voir cette question sur leur localisation .
0 votes
OT : Pour ceux qui veulent savoir où ces fonctions anonymes sont beaucoup utilisées, lisez svp adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
0 votes
Il s'agit d'un cas typique d'expressions de fonctions immédiatement invoquées (IIFE).