View on GitHub

Capacitacao-CEOS-2-Javascript

Arrow Functions

Em Javascript, normalmente criamos nossas funções utilizando a palavra function, seguida do nome da função e os seus parâmetros, além do corpo da função.

Porém, em alguns casos, essa sintaxe pode ser um pouco exaustiva e longa.

Na versão ES6 do Javascript, em 2015, foi introzido uma nova forma de criarmos funções: as chamadas Arrow Functions.

Como iremos ver a seguir, as Arrow Functions possuem uma sintaxe bem mais curta e enxuta que as funções comuns em Javascript.

Um detalhe importante, é que as arrow functions não possuem um nome, por isso, também podem ser chamadas de funções anônimas, por não ter um nome.

Para criar uma Arrow Function, normalmente usamos a sintaxe

(parametro1, parametro2) => {
    // codigo...
}

Por exemplo:

let primeiraArrow = () => { 
    console.log('ola mundo')
};
primeiraArrow();

Perceba que guardamos a função na variável primeiraArrow, isso acontece porque como arrow functions não possuem um nome,se não guardarmos ela em uma variável (ou de alguma outra maneira), ela não poderá ser usada, porque não temos como usar o nome dela na hora de chamar a função (funcao()).

Isso pode parecer meio ruim, ter que guardar a função em uma variável, porém o caso onde Arrow Functions realmente brilham, é quando precisamos passar uma função como parâmetro de outra função. Lembra do método Array.forEach? Esse é um exemplo de método que precisa de uma função como parâmetro.

Normalmente, teriamos que usar esse método da seguinte maneira:

Exemplo: elevando todos os elementos de um array ao quadrado

let arr = [1, 2, 3, 4, 5];

let quadrados = arr.map(function quadrado(valor, indice, array) {
    return valor * valor;
});

console.log(quadrados); // [1, 4, 9, 16, 25]

Porém, com **Arrow Functions, esse código pode ficar bem menor:

let arr = [1, 2, 3, 4, 5];

let quadrados = arr.map((valor, indice, array) => {
    return valor * valor;
});

console.log(quadrados); // [1, 4, 9, 16, 25]

Beleza, até que não diminuiu tanto, porém, quando a nossa função possui apenas uma linha, que nesse caso é o cálculo do valor ao quadrado, podemos remover o return e os dois { }.

let arr = [1, 2, 3, 4, 5];

let quadrados = arr.map((valor, indice, array) => valor * valor);

console.log(quadrados); // [1, 4, 9, 16, 25]

Nessa sintaxe de (parametro1, parametro2) => resultado, o valor que será retornado da função é a expressão resultado. Que no caso do exemplo anterior, era o cálculo do valor ao quadrado.

Perceba que agora ficou tudo bem mais curto, em uma única linha.

São nesses casos que as arrow functions brilham: pequenas funções, que geralmente não precisamos dar um nome para utilizar posteriormente.

Ainda temos como encurtar ainda mais essa função: removendo os parâmetros indice e array. Como não usamos esses parâmetros, podemos remover eles da função sem problemas. Isso não causa erros no Javascript.

Nesse caso, teremos apenas um único parâmetro, valor.

Quando temos um único parâmetro, podemos omitir os ( ) dos parâmetros da Arrow Function, e usar essa sintaxe: parametro => resultado. parametro é o único parâmetro da função, e resultado é o que será retornado da função. Dessa forma, nosso código fica bem enxuto:

let arr = [1, 2, 3, 4, 5];

let quadrados = arr.map(valor => valor * valor);

console.log(quadrados); // [1, 4, 9, 16, 25]

E são em casos assim que as Arrow Functions brilham. Quando temos pequenas funções que precisam ser passadas como parâmetro para uma outra função.

Porém, você também poderia utilizar funções normais, com function. A decisão é do programador nesse caso.

Porém, existe uma diferença quanto ao this com Arrow Functions.

Atenção: Antes de ler este parte, é bom ter lido e entendido bem o capítulo anterior (13 - this), pois essas partes dependem muito do entendimento do this.

Geralmente, o this de uma função depende de como ela é chamada. Porém, com Arrow Functions, o this será o mesmo this do contexto onde a Arrow Function foi definida.

Essa parte é BEM confusa, porém com exemplos fica mais claro:

Um exemplo:

let obj = {
    a: 15,
    metodo: function metodo() {
        console.log(this); // obj
        console.log(this.a); // 15

        let minhaArrow = () => {
            console.log(this);
            console.log(this.a);
        }
        minhaArrow(); // imprime o objeto 'obj' e 15
    }
}

Perceba que minhaArrow, mesmo sendo invocada diretamente com (), possui o mesmo this da função metodo. Isso acontece, porque o this foi passado da função metodo para a arrow function minhaArrow!

Esse é um outro caso de uso das arrows functions: quando estamos escrevendo código que depende muito do this, e queremos passar o this através do contexto, ao invés de como a função é invocada.

Porém, atenção: Arrow Functions não são interessantes para criar métodos de objetos, porque o this será o objeto global (window em navegadores).

Exemplo:

let meuObj = {
    a: 42,
    metodo: () => {
        console.log(this.a)
    }
}

meuObj.metodo(); // undefined, ooops, o `this` não é o objeto `meuObj` :p

Perceba novamente, que o this da Arrow Function depende do contexto onde a Arrow Function é definida.

Como esse código está fora de qualquer função, o this seria o objeto global, e não definimos a propriedade a no objeto global window (nos browsers). Portanto, this.a é undefined.

Existem outras sintaxes para arrow functions, porém num geral é bom se atermos a uma, no máximo duas, para termos um padrão no código.

Para mais informações, é muito útil consultar a documentação da MDN.

É bom estar atento aos casos de uso mais poderosos das Arrow Functions: funções curtas e sem nome, que geralmente são passadas para outras funções, ou então quando precisamos guardar o this do contexto onde a Arrow Function foi definida.