Como escrevo uma função de seta nomeada no ES2015?
Você faz isso da maneira que descartou em sua pergunta: você o coloca no lado direito de uma atribuição ou inicializador de propriedades em que a variável ou o nome da propriedade pode ser razoavelmente usado como um nome pelo mecanismo JavaScript. Não há outra maneira de fazer isso, mas fazer isso é correto e totalmente coberto pela especificação.
Por especificação, essa função tem um nome verdadeiro sayHello
:
var sayHello = name => {
console.log(name + ' says hello');
};
Isso é definido em Operadores de Designação> Semântica de Tempo de Execução: Avaliação, onde chama a SetFunctionName
operação abstrata (essa chamada está atualmente na etapa 1.e.iii).
Da mesma forma, o Runtime Semantics: PropertyDefinitionEvaluation chama SetFunctionName
e, portanto, atribui a essa função um nome verdadeiro:
let o = {
sayHello: name => {
console.log(`${name} says hello`);
}
};
Os mecanismos modernos definem o nome interno da função para declarações como essa; O Edge ainda tem o bit disponível, como name
na instância da função atrás de um sinalizador de tempo de execução.
Por exemplo, no Chrome ou Firefox, abra o console da Web e execute este trecho:
"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
foo();
} catch (e) {
console.log(e.stack);
}
No Chrome 51 e acima e Firefox 53 e acima (e Edge 13 e acima com um sinalizador experimental), quando você o executa, você verá:
foo.name é: foo
Erro
no foo (http://stacksnippets.net/js:14:23)
em http://stacksnippets.net/js:17:3
Observe o foo.name is: foo
e Error...at foo
.
No Chrome 50 e versões anteriores, Firefox 52 e versões anteriores e Edge sem o sinalizador experimental, você verá isso porque elas ainda não têm a Function#name
propriedade:
foo.name é:
Erro
no foo (http://stacksnippets.net/js:14:23)
em http://stacksnippets.net/js:17:3
Observe que o nome está ausente foo.name is:
, mas é mostrado no rastreamento da pilha. É que, na verdade, implementar a name
propriedade na função era de menor prioridade do que alguns outros recursos do ES2015; Chrome e Firefox têm agora; O Edge está atrás de uma bandeira, presumivelmente não ficará muito tempo atrás da bandeira.
Obviamente, só posso usar esta função depois de defini-la
Corrigir. Não há sintaxe de declaração de função para funções de seta, apenas sintaxe de expressão de função e não há seta equivalente ao nome em uma expressão de função denominada no estilo antigo ( var f = function foo() { };
). Portanto, não há 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
Você precisa dividi-lo em duas expressões (eu diria que você deveria fazer isso de qualquer maneira ) :
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));
Obviamente, se você precisar colocar isso onde uma única expressão é necessária, sempre poderá usar ... uma função de seta:
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
Não estou dizendo que isso seja bonito, mas funciona se você absolutamente, positivamente, precisar de um invólucro de expressão única.