Vamos revisitar as funções das setas.
As funções de seta não são apenas uma “abreviação” para escrever pequenas coisas. Eles têm alguns recursos muito específicos e úteis.
JavaScript está cheio de situações em que precisamos escrever uma pequena função que é executada em outro lugar.
Por exemplo:
arr.forEach(func)
– func
é executado por forEach
para cada item do array.
setTimeout(func)
– func
é executado pelo agendador integrado.
…há mais.
Está no espírito do JavaScript criar uma função e passá-la para algum lugar.
E nessas funções geralmente não queremos sair do contexto atual. É aí que as funções das setas são úteis.
Como lembramos do capítulo Métodos de objeto, "this", as funções de seta não possuem this
. Se this
acessado, é retirado de fora.
Por exemplo, podemos usá-lo para iterar dentro de um método de objeto:
deixe grupo = { título: "Nosso Grupo", alunos: ["John", "Pete", "Alice"], mostrarLista() { this.students.forEach( aluno => alerta(this.title + ':' + aluno) ); } }; grupo.showList();
Aqui em forEach
, a função de seta é usada, então this.title
é exatamente igual ao método externo showList
. Isto é: group.title
.
Se usássemos uma função “normal”, haveria um erro:
deixe grupo = { título: "Nosso Grupo", alunos: ["John", "Pete", "Alice"], mostrarLista() { this.students.forEach(função(aluno) { // Erro: Não é possível ler a propriedade 'título' de indefinido alert(this.title + ': ' + aluno); }); } }; grupo.showList();
O erro ocorre porque forEach
executa funções com this=undefined
por padrão, então é feita a tentativa de acessar undefined.title
.
Isso não afeta as funções de seta, porque elas simplesmente não possuem this
.
As funções de seta não podem ser executadas com new
Não ter this
naturalmente significa outra limitação: funções de seta não podem ser usadas como construtores. Eles não podem ser chamados com new
.
Funções de seta VS bind
Há uma diferença sutil entre uma função de seta =>
e uma função regular chamada com .bind(this)
:
.bind(this)
cria uma “versão vinculada” da função.
A seta =>
não cria nenhuma ligação. A função simplesmente não tem this
. A pesquisa this
é feita exatamente da mesma forma que uma pesquisa de variável regular: no ambiente lexical externo.
As funções de seta também não possuem variáveis arguments
.
Isso é ótimo para decoradores, quando precisamos encaminhar uma chamada com o this
e arguments
atuais.
Por exemplo, defer(f, ms)
obtém uma função e retorna um wrapper em torno dela que atrasa a chamada em ms
milissegundos:
função adiar(f, ms) { função de retorno() { setTimeout(() => f.apply(this, argumentos), ms); }; } function digaOi(quem) { alert('Olá, ' + quem); } deixe dizerHiDeferred = adiar(sayHi, 2000); sayHiDeferred("João"); // Olá, John após 2 segundos
O mesmo sem uma função de seta seria:
função adiar(f, ms) { função de retorno(...args) { deixe ctx = isso; setTimeout(função(){ retornar f.apply(ctx, args); }, EM); }; }
Aqui tivemos que criar variáveis adicionais args
e ctx
para que a função dentro de setTimeout
pudesse aceitá-las.
Funções de seta:
Não tenho this
Não tenha arguments
Não pode ser chamado com new
Eles também não têm super
, mas ainda não estudamos. Iremos no capítulo Herança de classe
Isso porque eles são destinados a pequenos trechos de código que não possuem “contexto” próprio, mas funcionam no atual. E eles realmente brilham nesse caso de uso.