web-dev-qa-db-fra.com

Invocation / exécution immédiate de la fonction anonyme JavaScript (expression vs déclaration)

Doublons possibles:
Quelle est la différence entre une expression de fonction et une déclaration en JavaScript?
Expliquez la syntaxe de la fonction anonyme encapsulée de JavaScript

Pourquoi ça:

(function () {
    //code
}());

et ça:

var f = function () {
    //code
}();

fonctionne, alors que ceci:

function () {
    //code
}();

ne fait pas? Il a exactement la même apparence - fonction anonyme définie et immédiatement appelée. Quelqu'un peut-il faire un devis à partir de la norme JavaScript/ECMAScript qui explique cela?

[~ # ~] mise à jour [~ # ~] : Merci pour les réponses à tous! Il s'agit donc de expression de fonction vs déclaration de fonction . Voir cette réponse Stack Overflow , norme ECMAScript section 13, et cet excellent article: Les expressions de fonction nommées démystifiées .

Pour récapituler les réponses:

  1. Le premier extrait est interprété comme une expression car l'opérateur de regroupement, (), est appliqué - voir norme ECMAScript section 11.1.6.

  2. Dans le deuxième extrait de code, la fonction est interprétée comme une expression car elle se trouve dans la partie droite de l'opérateur d'affectation, =.

  3. Le troisième extrait de code n'a rien qui permette à l'interpréteur de lire la fonction comme une expression, il est donc considéré comme une déclaration, qui est invalide sans identifiant (Gecko le laisse cependant passer, mais il s'étouffe en suivant () opérateur de regroupement (comme il le pense) appliqué à rien).

58
lxa

Les deux premiers cas affichent les expressions de fonction , et peuvent apparaître n'importe où une expression comme (1+1 Ou x*f(4)) serait apparaître. Tout comme la façon dont 1+1 Est évalué à 2, Ces expressions sont évaluées en fonction correspondante.


Le troisième cas est une décomposition de la fonction instruction, et peut apparaître n'importe où vous pouvez avoir d'autres instructions (comme un if ou while).

Il ne sert à rien d'essayer de déclarer une fonction anonyme via une déclaration de déclaration Funcion, car sinon personne n'obtiendrait une référence à la fonction par la suite.


La raison pour laquelle vous avez besoin de l'ouverture ( Ou du var x = Comme dans les deux premiers cas est qu'ils forcent le bit suivant à être analysé dans un contexte d'expression. (pensez simplement à comment vous ne pouvez pas faire var x = if ..., par exemple). Si vous venez de mettre le function comme première chose, il sera analysé comme la déclaration déclaration que vous ne voulez pas.

21
hugomg

Les deux premiers sont quelque chose appelé une expression de fonction, ce qui signifie qu'elle est intégrée et interprétée lors de l'exécution du code JS.

La 3e est une déclaration de fonction et est interprétée lors de la compilation du code. Puisqu'il est interprété lors de la compilation, vous ne pouvez pas l'exécuter immédiatement car aucun des autres codes qui l'entourent n'a encore été exécuté.

Pour montrer un exemple:

// foo == undefined
// bar == function

function bar(){ .. }
var foo = function(){ ... }

// foo == function
// bar == function

En termes simples, chaque fois que vous avez le mot function sans que rien ne le précède, c'est une déclaration. Chaque fois que quelque chose le précède, c'est une expression.

4
Mark Kahn

Les fonctions anonymes sont bien expliquées dans la question Stack Overflow Pourquoi avez-vous besoin d'invoquer une fonction anonyme sur la même ligne?.

0
Jason Gennaro

Voici une manière simple d'y penser: si function est le premier mot-clé de la ligne, l'analyseur interprétera le reste de la ligne comme une déclaration de fonction. En d'autres termes, il pensera que vous essayez d'écrire quelque chose comme ça, comme si vous avez oublié de nommer votre fonction:

function foo(){ 
    // code
}

La façon de contourner ce problème consiste à envelopper la fonction entière dans des parens ou à l'intégrer à une affectation de variable. Dans les deux cas, vous remettez function plus loin sur la ligne et vous permettez à l'analyseur de reconnaître que vous n'écrivez pas de déclaration de fonction.

Cela me semble un peu trivial de permettre à function d'apparaître au début d'une ligne et de toujours faire la distinction entre les expressions de fonction et les déclarations de fonction, mais je suppose que ce n'était pas si trivial lorsque JavaScript a été conçu pour la première fois.

0
Andrew