¿Cómo escribo una función de flecha con nombre en ES2015?
Lo hace de la manera que descartó en su pregunta: lo coloca en el lado derecho de una asignación o inicializador de propiedad donde el motor de JavaScript puede usar razonablemente la variable o el nombre de la propiedad como nombre. No hay otra forma de hacerlo, pero hacerlo es correcto y está completamente cubierto por la especificación.
Por especificación, esta función tiene un nombre verdadero sayHello
:
var sayHello = name => {
console.log(name + ' says hello');
};
Esto se define en Operadores de asignación> Semántica de tiempo de ejecución: evaluación donde llama a la SetFunctionName
operación abstracta (esa llamada se encuentra actualmente en el paso 1.e.iii).
De manera similar, Runtime Semantics: PropertyDefinitionEvaluation llama SetFunctionName
y, por lo tanto, le da a esta función un nombre verdadero:
let o = {
sayHello: name => {
console.log(`${name} says hello`);
}
};
Los motores modernos ya establecen el nombre interno de la función para declaraciones como esa; Edge todavía tiene el bit que lo hace disponible como name
en la instancia de la función detrás de un indicador de tiempo de ejecución.
Por ejemplo, en Chrome o Firefox, abra la consola web y luego ejecute este fragmento:
"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
foo();
} catch (e) {
console.log(e.stack);
}
En Chrome 51 y superior y Firefox 53 y superior (y Edge 13 y superior con una marca experimental), cuando ejecute eso, verá:
foo.name es: foo
Error
en foo (http://stacksnippets.net/js:14:23)
en http://stacksnippets.net/js:17:3
Tenga en cuenta la foo.name is: foo
y Error...at foo
.
En Chrome 50 y versiones anteriores, Firefox 52 y versiones anteriores, y Edge sin la marca experimental, verás esto porque no tienen la Function#name
propiedad (todavía):
foo.name es:
Error
en foo (http://stacksnippets.net/js:14:23)
en http://stacksnippets.net/js:17:3
Tenga en cuenta que el nombre no se encuentra en foo.name is:
, pero se muestra en el seguimiento de la pila. Es solo que realmente implementando la name
propiedad en la función era de menor prioridad que otras características de ES2015; Chrome y Firefox lo tienen ahora; Edge lo tiene detrás de una bandera, presumiblemente ya no estará detrás de la bandera por mucho tiempo.
Obviamente, solo puedo usar esta función después de haberla definido
Correcto. No hay sintaxis de declaración de función para las funciones de flecha, solo la sintaxis de expresión de función , y no hay una flecha equivalente al nombre en una expresión de función con nombre de estilo antiguo ( var f = function foo() { };
). Entonces no hay equivalente a:
console.log(function fact(n) {
if (n < 0) {
throw new Error("Not defined for negative numbers");
}
return n == 0 ? 1 : n * fact(n - 1);
}(5)); // 120
Tienes que dividirlo en dos expresiones (argumentaría que deberías hacerlo de todos modos ) :
let fact = n => {
if (n < 0) {
throw new Error("Not defined for negative numbers.");
}
return n == 0 ? 1 : n * fact(n - 1);
};
console.log(fact(5));
Por supuesto, si tiene que poner esto donde se requiere una sola expresión, siempre puede ... usar una función de flecha:
console.log((() => {
let fact = n => {
if (n < 0) {
throw new Error("Not defined for negative numbers.");
}
return n == 0 ? 1 : n * fact(n - 1);
};
return fact(5);
})()); // 120
No digo que sea bonito, pero funciona si necesitas absolutamente un contenedor de expresión.