En el caso de la expresión de función anónima, la función es anónima ; literalmente, no tiene nombre. La variable a la que lo está asignando tiene un nombre, pero la función no. (Actualización: Eso fue cierto a través de ES5. A partir de ES2015 [también conocido como ES6], a menudo una función creada con una expresión anónima obtiene un nombre verdadero [pero no un identificador automático], sigue leyendo ...)
Los nombres son útiles. Los nombres se pueden ver en seguimientos de pila, pilas de llamadas, listas de puntos de interrupción, etc. Los nombres son algo bueno ™.
(Solía tener que tener cuidado con las expresiones de función con nombre en versiones anteriores de IE [IE8 y anteriores], porque crearon por error dos objetos de función completamente separados en dos momentos completamente diferentes [más en el artículo de mi blog Doble toma ]. Si es necesario admite IE8 [!!], probablemente sea mejor seguir con expresiones de función anónimas o declaraciones de función , pero evite las expresiones de función con nombre).
Una cosa clave acerca de una expresión de función nombrada es que crea un identificador dentro del alcance con ese nombre para la función dentro del cuerpo de la función:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
Sin embargo, a partir de ES2015, muchas expresiones de función "anónimas" crean funciones con nombres, y esto fue precedido por varios motores JavaScript modernos que son bastante inteligentes para inferir nombres a partir del contexto. En ES2015, su expresión de función anónima da como resultado una función con el nombre boo
. Sin embargo, incluso con la semántica de ES2015 +, no se crea el identificador automático:
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();
La asignación del nombre de la función se realiza con la operación abstracta SetFunctionName utilizada en varias operaciones en la especificación.
La versión corta es básicamente cada vez que aparece una expresión de función anónima en el lado derecho de algo como una asignación o inicialización, como:
var boo = function() { /*...*/ };
(o podría ser let
o en const
lugar de var
) , o
var obj = {
boo: function() { /*...*/ }
};
o
doSomething({
boo: function() { /*...*/ }
});
(esos dos últimos son realmente lo mismo) , la función resultante tendrá un nombre (boo
, en los ejemplos).
Hay una excepción importante e intencionada: asignar una propiedad a un objeto existente:
obj.boo = function() { /*...*/ }; // <== Does not get a name
Esto se debió a las preocupaciones sobre la filtración de información que surgieron cuando la nueva función estaba en proceso de ser agregada; detalles en mi respuesta a otra pregunta aquí .