396 votes

Expliquer la syntaxe de la fonction anonyme encapsulée.

Resumen

Pouvez-vous expliquer le raisonnement qui sous-tend la syntaxe des fonctions anonymes encapsulées en JavaScript ? Pourquoi cela fonctionne-t-il ? (function(){})(); mais ce n'est pas le cas : function(){}(); ?


Ce que je sais

En JavaScript, on crée une fonction nommée comme ceci :

function twoPlusTwo(){
    alert(2 + 2);
}
twoPlusTwo();

Vous pouvez également créer une fonction anonyme et l'affecter à une variable :

var twoPlusTwo = function(){
    alert(2 + 2);
};
twoPlusTwo();

Vous pouvez encapsuler un bloc de code en créant une fonction anonyme, puis en l'entourant de parenthèses et en l'exécutant immédiatement :

(function(){
    alert(2 + 2);
})();

Ceci est utile lors de la création de scripts modulaires, pour éviter d'encombrer la portée actuelle, ou la portée globale, avec des variables potentiellement conflictuelles - comme dans le cas des scripts Greasemonkey, des plugins jQuery, etc.

Maintenant, je comprends pourquoi ça marche. Les parenthèses enferment le contenu et n'exposent que le résultat (je suis sûr qu'il y a une meilleure façon de décrire cela), comme avec (2 + 2) === 4 .


Ce que je ne comprends pas

Mais je ne comprends pas pourquoi cela ne fonctionne pas aussi bien :

function(){
    alert(2 + 2);
}();

Vous pouvez m'expliquer ça ?

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

3voto

bosonix Points 1104

J'ai juste une autre petite remarque. Votre code fonctionnera avec une petite modification :

var x = function(){
    alert(2 + 2);
}();

J'utilise la syntaxe ci-dessus au lieu de la version la plus répandue :

var module = (function(){
    alert(2 + 2);
})();

parce que je n'ai pas réussi à faire fonctionner correctement l'indentation pour les fichiers javascript dans vim. Il semble que vim n'aime pas les accolades à l'intérieur des parenthèses ouvertes.

0 votes

Alors pourquoi cette syntaxe fonctionne-t-elle lorsque vous affectez le résultat exécuté à une variable, mais pas de manière autonome ?

1 votes

@paislee -- Parce que le moteur JavaScript interprète toute déclaration JavaScript valide commençant par l'icône function comme un déclaration de fonction dans ce cas, la dernière ligne () est interprété comme un opérateur de groupage qui, selon les règles de syntaxe JavaScript, peut seulement et debe contient une expression JavaScript.

2 votes

@bosonix -- Votre syntaxe préférée fonctionne bien, mais c'est une bonne idée d'utiliser soit la "version la plus répandue" que vous avez référencée, soit la variante dans laquelle () est entouré de l'opérateur de regroupement (celui que Douglas Crockford recommande fortement) par souci de cohérence : il est courant d'utiliser des IIFE sans les affecter à une variable, et il est facile d'oublier d'inclure ces parenthèses de regroupement si vous ne les utilisez pas de manière cohérente.

2voto

Vithy Points 21
(function(){
     alert(2 + 2);
 })();

La syntaxe ci-dessus est valide car tout ce qui est passé entre parenthèses est considéré comme une expression de fonction.

function(){
    alert(2 + 2);
}();

La syntaxe ci-dessus n'est pas valide. Parce que l'analyseur syntaxique java script cherche le nom de la fonction après le mot-clé function puisqu'il ne trouve rien il jette une erreur.

0voto

theking2 Points 133

La réponse la plus courte serait peut-être que

function() { alert( 2 + 2 ); }

est un fonction littérale que define une fonction (anonyme). Une paire de ()supplémentaires, qui est interprétée comme une expression, n'est pas attendue au toplevel, seulement des littéraux.

(function() { alert( 2 + 2 ); })();

est dans un déclaration d'expression que invoque une fonction anonyme.

0voto

Jude Points 1274

Ils peuvent être utilisés avec des paramètres-arguments tels que

var x = 3; 
var y = 4;

(function(a,b){alert(a + b)})(x,y)

serait le résultat de 7

0voto

Jarkko Hietala Points 1

Ces parenthèses supplémentaires créent des fonctions anonymes supplémentaires entre l'espace de nom global et la fonction anonyme qui contient le code. Et en Javascript, les fonctions déclarées à l'intérieur d'autres fonctions ne peuvent accéder qu'à l'espace de nom de la fonction parente qui les contient. Comme il y a un objet supplémentaire (fonction anonyme) entre la portée globale et le code réel, le scoping n'est pas conservé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X