Entendendo Arrow Functions de uma vez por todas
A versão ES6 do ECMAScript adicionou muito recursos interessantes ao JavaScript. Mas, um recurso que se destacou com certeza foram as arrow functions. Elas são basicamente uma nova forma de criar funções com JavaScript, com uma estrutura mais curta, mas bem poderosa ao mesmo tempo.
Sintaxe básica
Uma função convencional pode ser criada com este código:
function() {}
Já a sintaxe básica de uma arrow function é a seguinte:
() => {}
Note que não escrevemos “function”. Além disso, usamos o sinal “=>” para criá-la, o que lembra uma flecha, fazendo jus ao nome “Arrow Functions”.
Quando vemos essa estrutura, notamos que é uma forma mais elegante e “bonita” de criar funções. Mas as arrow functions são muito mais que apenas isso. Elas possuem muitos recursos poderosos, que iremos falar agora.
Recursos das Arrow Functions
Um ponto interessante das arrow functions é a questão do return destas funções. Se nossa função possuir apenas um comando return, não precisamos informá-lo, mas apenas o valor que queremos retornar. Imagine que desejamos criar uma função que irá retornar uma mensagem de boas vindas para uma pessoa, levando em conta o nome que iremos informar como parâmetro. Essa função poderia ser criada com o seguinte código:
const sayHello = function(name) {
return `Seja bem-vindo ${name}!!!`;
}
Essa função executaria bem, mas usamos três linhas de código para retornar uma mensagem. Contudo, nós podemos obter o mesmo resultado com a seguinte arrow function:
const sayHello = name => `Seja bem-vindo ${name}!!!`;
Se executarmos sayHello('Mark'), veremos o seguinte:
Excelente, a função funcionou (perdão pelo pleonasmo ?). Bem mais simples, não acha? Nós conseguimos refatorar uma função que ocupava três linhas, resumindo-a em apenas uma linha, o que é ótimo.
Note que o parâmetro name foi definido sem parênteses. Isso ocorre pois ele é um parâmetro único na função. Entretanto, se ela possuísse mais de um parâmetro, seríamos obrigados a colocar os parênteses. Podemos ver isso em um segundo exemplo.
Imagine que desejamos criar uma função que irá realizar qualquer cálculo para nós. Ela irá esperar três parâmetros: os dois números para realizar o cálculo e a operação da conta. Poderíamos definir essa função com este código:
const calc = (num1, num2, operator) => "Resultado: " + eval(`${num1} ${operator} ${num2}`);
Se executarmos calc(4, 5, '*'), veremos o seguinte resultado:
O código funcionou corretamente. Mas, note que foi necessário informar os parâmetros com parênteses para que isso fosse possível.
Um outro recurso do ECMAScript 6 que podemos usar com as arrow functions é a desestruturação (Destructuring). Nós podemos usar essa sintaxe para definir, por exemplo, valores padrão para os parâmetros de uma função. Imagine agora que desejamos informar apenas a operação para a função calc(), e ela deverá realizar um cálculo com números já definidos. Isso seria possível com esse código:
const calc = (operator, [num1, num2] = [2, 3]) => "Resultado: " + eval(`${num1} ${operator} ${num2}`);
Assim, se não informamos nenhum valor para a função, os números 2 e 3 serão usados para realizar a conta. Isso significa que podemos executar o seguinte código:
calc('+')
Ao executá-lo, nós não iremos ver um erro, mas sim o seguinte resultado:
A operação foi executada corretamente com base nos valores padrão. O tema de Destructuring é muito interessante. Gostariam que escrevêssemos um artigo sobre ele? Você pode enviar suas sugestões para nós clicando aqui.
Esses são alguns recursos que podemos utilizar com as arrow functions. Contudo, há um outro recurso que podemos usar bastante em nosso favor: a falta de mudança de escopo.
Arrow Functions e escopo de variáveis
A linguagem JavaScript possui o que chamamos de escopo de variáveis. Podemos dizer que esse conceito é, em poucas palavras, a maneira que as variáveis são identificadas ou “enxergadas” em nosso código. As variáveis que são criadas na “raiz” de nosso código estão no escopo global.
Contudo, quando criamos uma função, um novo escopo é criado. Assim, as variáveis criadas lá dentro são “enxergadas”, ou identificadas, apenas lá. Além disso, podemos nos referir a essa nova função com a palavra reservadas this.
E é nesse ponto que as arrow functions se destacam. Elas não criam um novo escopo. Isso significa que elas não possuem um this. Talvez de início pensemos: “Mas que coisa mais estranha.” Entretanto, é interessante encarar essa peculiaridade das arrow functions como um recurso, que pode nos ajudar em algumas situações.
Veja um exemplo: vamos criar uma classe que irá possuir um atributo chamado list, que irá conter um array vazio. Daí, iremos criar um método que possuirá o objetivo de adicionar novos valores a este array. A estrutura da classe será a seguinte:
class Hcode {
constructor(){
this.list = [];
this.pushArray();
}
pushArray(){
let newList = [1, 2, 3];
newList.forEach(function(value) {
this.list.push(value);
});
console.log(this.list);
}
}
Perceba que estamos usando uma função convencional no forEach() que está dentro do método pushArray(). Ao instanciar a classe Hcode, vemos o seguinte resultado:
O erro informa um problema com o atributo list. Isso ocorre pois essa função que está dentro do laço de repetição criou um novo escopo, que não conseguiu encontrar dentro de seu this uma propriedade chamada list. Ela realmente não existe neste escopo. Quando digitamos this.list, queremos nos referir ao atributo list de nossa classe, que está em outro escopo, ou contexto. Nessa situação as arrow functions podem nos ajudar. Vamos substituir esse forEach() por esse código:
newList.forEach(value => {
this.list.push(value);
});
Ao instanciar a classe Hcode, vemos o seguinte:
Os itens foram adicionados ao array sem erros! Agora o código funcionou pois o this estava se referindo ao escopo global.
Esse exemplo nos ajuda inclusive a responder uma pergunta muito comum: “Quando devo usar arrow functions?” Como vimos neste artigo, as arrow functions são muito poderosas, além de representar um código mais elegante e conciso. Se for necessário criar alguma função que necessite realizar referência a seu próprio escopo dentro de si, as arrow functions não são recomendadas. Contudo, se não for esse o caso, você poderá usá-las em grande parte de seus projetos tranquilamente, o que deixará seus códigos ainda mais modernos e poderosos.
Lembrando que falamos sobre as Arrow Functions e muitos outros recursos do JavaScript em nosso Curso Completo de JavaScript, onde desenvolvemos 7 projetos reais incríveis usando essa linguagem sensacional, sempre com o método Hcode de ensino.
A gente se vê no próximo artigo :)