Dans le cas de l'expression de fonction anonyme, la fonction est anonyme - littéralement, elle n'a pas de nom. La variable à laquelle vous l'affectez a un nom, mais pas la fonction. (Mise à jour: c'était vrai via ES5. Depuis ES2015 [aka ES6], souvent une fonction créée avec une expression anonyme obtient un vrai nom [mais pas un identifiant automatique], lisez la suite ...)
Les noms sont utiles. Les noms peuvent être vus dans les traces de pile, les piles d'appels, les listes de points d'arrêt, etc. Les noms sont une bonne chose ™.
(Vous deviez vous méfier des expressions de fonction nommées dans les anciennes versions d'IE [IE8 et versions antérieures], car elles créaient par erreur deux objets de fonction complètement séparés à deux moments complètement différents [plus dans mon article de blog Double prise ]. Si vous devez supporte IE8 [!!], il est probablement préférable de s'en tenir aux expressions de fonction anonymes ou aux déclarations de fonction , mais évitez les expressions de fonction nommées.)
Une chose clé à propos d'une expression de fonction nommée est qu'elle crée un identificateur dans la portée avec ce nom pour la fonction dans le corps de la fonction:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
Depuis ES2015, cependant, beaucoup d'expressions de fonction «anonymes» créent des fonctions avec des noms, et cela a été précédé par divers moteurs JavaScript modernes qui étaient assez intelligents pour déduire des noms à partir du contexte. Dans ES2015, votre expression de fonction anonyme entraîne une fonction avec le nom boo
. Cependant, même avec la sémantique ES2015 +, l'identifiant automatique n'est pas créé:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
L'affectation du nom de la fonction est effectuée avec l' opération abstraite SetFunctionName utilisée dans diverses opérations de la spécification.
La version courte est essentiellement à chaque fois qu'une expression de fonction anonyme apparaît sur le côté droit de quelque chose comme une affectation ou une initialisation, comme:
var boo = function() { /*...*/ };
(ou cela pourrait être let
ou const
plutôt que var
) , ou
var obj = {
boo: function() { /*...*/ }
};
ou
doSomething({
boo: function() { /*...*/ }
});
(ces deux derniers sont vraiment la même chose) , la fonction résultante aura un nom ( boo
, dans les exemples).
Il existe une exception importante et intentionnelle: l'attribution à une propriété sur un objet existant:
obj.boo = function() { /*...*/ }; // <== Does not get a name
Cela était dû aux problèmes de fuite d'informations soulevés lorsque la nouvelle fonctionnalité était en cours d'ajout; détails dans ma réponse à une autre question ici .