Qu'est-ce qui détermine si une fonction JavaScript est une fonction anonyme nommée par rapport à une fonction régulière?

Lecture "Une réintroduction vers JavaScript" J'ai remarqué quelque chose d'intéressant sur les fonctions:

Le nom fourni à une fonction anonyme comme ci-dessus est (ou du moins devrait être) uniquement disponible à la portée de la fonction.

En entrant certaines choses en fonction du code dans le didacticiel à l'invite nodejs, j'ai pu vérifier que ce nœud accepte l'auteur:

function add(foo, bar) { return foo + bar; } add(1, 2); 

Obtient 3, et:

 var five = (function plus(foo, bar) { return foo + bar; })(2, 3); plus(2, 3); 

Obtient une erreur de syntaxe sur plus ne pas être définie.

Je suis un peu confus parce que le code que j'ai utilisé pour définir les deux fonctions était identique (sauf le nom). Comment JavaScript sait-il que le premier est une fonction régulière et le second est une fonction anonyme nommée?

La première est une déclaration de fonction normale. Le nom déclaré est introduit dans la portée actuelle et se réfère implicitement au corps de la fonction. Dans cette forme, la function est une déclaration et, en tant que telle, ne renvoie aucune valeur.

La seconde est une expression de fonction , et l'interprète le sait parce que c'est une partie du côté droit d'une tâche, et à cause de l'orthèse autour d'elle. Chaque fois que le mot function apparaît où une autre "valeur" (ou "expression") aurait pu être fournie, alors ce que vous avez est une expression de fonction. Le résultat de cette expression est une référence au corps de fonction.

Le nom d'une expression de fonction (si elle en a été donnée) n'est disponible que dans la fonction, comme décrit dans votre lien.

IMHO la nomenclature dans ce lien est incorrecte. Ce qu'ils appellent «fonctions anonymes nommées» devrait, à mon avis, être appelé «expression de fonction nommée». Cette erreur apparente peut résulter du fait que toutes les fonctions anonymes sont en fait des expressions de fonction, mais toutes les expressions de fonctions ne sont pas anonymes.

Notez que si vous utilisez ce style:

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

Alors comme décrit ci-dessus, la bar est une expression de fonction, dont le résultat est ensuite attribué à la variable foo . La bar noms n'est pas placée dans la portée actuelle, mais elle est disponible dans la fonction elle-même.

La déclaration de la variable foo sera hissée au sommet de la portée, mais on n'attribuera pas sa valeur (c'est-à-dire la référence à l'expression de la fonction) jusqu'à ce que la ligne ci-dessus soit effectivement exécutée.

Une autre démonstration intéressante de la différence est celle (depuis la console Chrome):

 > function() { } SyntaxError: Unexpected token ( > a = function() { } function () { } 

Notez que la seule différence est que dans le dernier cas, il y a une affectation à a . La tentative de déclarer une fonction anonyme à l'aide d'une déclaration est illégale, car la grammaire linguistique exige que l'instruction de fonction inclue une étiquette pour la fonction. Cependant, cette dernière est implicitement une expression de fonction, qui est autorisée à être anonyme.