Dominando o “this” do JavaScript – 6/6

No post anterior mostrei a última das cinco regras que permitem manipular o “this” do JavaScript. Essas cinco regras estão no JavaScript por algum tempo já. Mas no ES6, oficialmente chamado e ES2015, como a última e maior padronização da linguagem JavaScript, temos agora outra regra.

Felizmente, esta regra não é outra sintaxe do balacobaco, mas uma simplificação absorvida de outras linguagens com intuito de reduzir códigos nas funções callback e no gerenciamento do “this” mais logicamente.

 

Funções Seta do ES6


Com o ES6, uma função callback pode ser definida utilizando a nova sintaxe “função seta”. Esta sintaxe permite que você se livre da palavra “function” e coloque o símbolo “=>” entre a lista de parâmetros e o corpo da função.

Existem diversas variações da sintaxe, dependendo do número de argumentos e linhas de código na função. Não importa que versão de sintaxe você utilize, todas usam a mesma lógica:


exemplo( (arg1, arg2, arg3) => {
  // corpo da função
});

Se você fosse escrever a mesma função sem a notação “seta”, a função seria assim:


exemplo( function(arg1, arg2, arg3) {
  // corpo da função
});

É possível reduzir ainda mais a função seta, a diferença entre ela e a função padrão é insignificante quando você observa o número de caracteres a digitar.
A grande vantagem da função seta não é a redução da sintaxe, mas a forma que ela gerencia o “this” para você.

 

Escopo léxico

Quando você escreve uma função seta no JavaScript, o valor do “this” será determinado através da “análise léxica”. Esta é uma frase pomposa pra dizer que o “this” depende do código adjacente, de onde a função é chamada.

Segue um exemplo simples para ilustrar:


var empresa = {
  adicionaColaborador: function(){
                         var detalhe = this.getDetalhe();
                         // aqui usaremos a função seta (=>)
                         detalhe.on("complete", (colaborador) => {
                           // o "this" vem através do seguinte código
                           this.selecionaGerente(colaborador);
                         });
                       },
  selecionaGerente: function(colaborador) {
                      // pesquisa o gerente do colaborador
                    }
};


Note que não existe nenhuma gambi tipo “novo = this” ou “.bind”, “.call” ou “.apply”. Não há nada nesse código que defina explicitamente qual o valor que o “this” terá quando a função “this.selecionaGerente(colaborador)” for chamada.

A sintaxe da função seta se utiliza do contexto de onde o código pertence e verifica se pode usar a função pai como valor do “this”. Em outras palavras, o valor do “this” na função “adicionaColaborador” também será o valor do “this” dentro da função callback do gerenciador de eventos (no .on(“complete”…. ) ).
Isso traz muitos benefícios como você pode imaginar. Mas isso não resolve todos os casos do “this” e não te livra da utilização das outras regras já abordadas.

 

Alterando o código adjacente “this” altera também a função seta

Quando utilizamos o código “empresa” acima, o valor do “this” dentro da função “adicionaColaborador” é regido pelas mesmas regras padrão do “this”. Se você chama o método desta forma:


empresa.adicionaColaborador();

Então o valor do “this” dentro da função “adicionaColaborador” e dentro da função seta de callback será o objeto “empresa”. Entretanto, se você muda o padrão de invocação para o “adicionaColaborador”, você mudará também o valor do “this” em ambos locais:


var adiciona = empresa.adicionaColaborador;
adiciona();

Neste exemplo, o padrão de chamada de função simples foi utilizado, deixando o valor do “this” ser tanto o objeto global ou undefined se o código está em “strict mode”. Quando o código atinge o callback do evento “complete”, o valor do “this” não será o esperado. A função callback falhará porque o “this” não está apontando para o objeto “empresa”, logo, o método “selecionaGerente” não será encontrado;

 

Vale 10x seu peso em código deletado

O perigo no valor do “this” das funções seta podem soar dramáticas, mas não tem diferença dos mesmos problemas ao usar o “this” como “novo = this;” ou “.apply” ou qualquer outro método de gerenciamento do “this” no JavaScript. Os benefícios da nova sintaxe da função seta se sobressaem aos potenciais problemas de sua utilização.

Logo, utilize a sintaxe das funções seta no seu código JavaScript assim que puder. Esta funcionalidade vale o peso mental (e potenciais ferramentas que executam código ES6 atualmente) e o peso de todo código que você pode eliminar. Você não terá com o que se preocupar com “novo = this”, ou “.bind”, “.call” e “.apply” quando trabalhar com funções seta. Você somente deverá gerenciar o valor do “this” nos códigos adjacentes, que é algo que você já faz.

 

Uma jornada épica

Neste momento, você completou a jornada do Dominando o “this” do JavaScript!!!
Parabéns pela garra! Se você fez todos os exemplos de todos os posts, você perceberá que o “this” não é mais aquela pedra no meio do seu código e nem a desgraça da sua vida de desenvolvedor. Não se preocupe se você ainda se sente meio perdido aqui. Existe muita coisa a ser feita, a se praticar e aprender. Então, volte aos posts em que você ainda está com alguma dúvida e continue praticando. A prática leva à perfeição!

 

Mais uma coisinha

Antes de finalizar, vou criar outro post brevemente.

Eu não mostrei o detalhe da utilização do “.bind” sem falar mais sobre o que ele pode fazer por você. Se você der uma olhada na documentação, por exemplo, você verá mais do que somente associação de contexto. No próximo post, como um bônus, vou mostrar como você pode utilizar o “.bind” para aplicar parcialmente em funções, suprindo uma lista de parâmetros a uma função que então não será preciso especificar posteriormente.

Então fique ligado para o post Bônus da série Dominando o “this” do JavaScript!
Se houver alguma dúvida, sugestão ou percebeu algum erro de digitação, não hesite em entrar em contato que responderei tão rápido quanto puder e atribuirei o crédito pela ajuda.

Até mais!
André Fellows

Leave a Reply Cancel reply