> For the complete documentation index, see [llms.txt](https://uclsanca.gitbook.io/learn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://uclsanca.gitbook.io/learn/web-basico/javascript/arrow-functions.md).

# Arrow Functions

## O que são Arrow functions?

*Arrow function* é o termo dado para uma sintaxe específica de declaração de funções. Exemplo:

```javascript
// Forma usual de declarar funções
function funcaoNormal (arg1, arg2) {
    // Add Code Here
}

// Arrow function.
const arrowFunction = (arg1, arg2) => {
    // Add Code Here
}
```

A sintaxe geral de uma *Arrow Function* é uma lista de argumentos entre parênteses, uma flecha "=>", e um bloco de código (entre chaves). Então, uma *Arrow Function* que recebe dois argumentos (nomeados "A" e "B"), e retorna a soma deles, pode ser declarada assim: `(A, B) => { return A + B }`.

Note no bloco de código acima que, diferente da declaração usual de funções, a declaração dessa *arrow function* começou com a declaração de uma variável, que então recebeu a função em si. Isso acontece porque as *Arrow Functions* não tem um nome, e precisam, então, ser guardadas em variáveis. Esse comportamento só é possível porque, em JavaScript, funções são um tipo de valor (como números ou strings), que pode ser atribuído para qualquer variável (essa propriedade também é conhecida como *Functions as First Class Citizens*).

Como *Arrow Functions* são apenas um tipo de função, elas podem ser chamadas da exata mesma forma que funções normais. Usando o bloco acima de exemplo, as chamadas podem ser feitas assim:

```javascript
funcaoNormal('valor1', 'valor2');

// Chamada de uma Arrow Function. Idêntica a chamada de uma função normal.
arrowFunction('valor1', 'valor2');
```

## Por que usar Arrow Functions?

### Não usa um nome

Como *Arrow Functions* não necessariamente precisam ser nomeadas, elas podem ser mais facilmente usadas como argumentos de outras funções. Um exemplo claro disso é com o `setTimeout`:

```javascript
// ----------------------- Declaração usual de funções -----------------------
function timeoutCallback () {
    // Code
}

setTimeout(timeoutCallback, 1000);

// ----------------------------- Arrow Function ------------------------------
setTimeout(() => {
    // Code
}, 1000);
```

Com uma *Arrow Function*, não precisamos nomear a função de callback do `setTimeout`. Assim, não "sujamos" o nosso escopo de variáveis com um nome que poderia ser evitado, e ainda conseguimos deixar o código relativo ao `setTimeout` dentro da chamada deste, potencialmente facilitando a legibilidade.

### A Arrow Function pode ser atribuída à uma variável constante

Na declaração usual de funções, é possível "redeclarar" funções, como no seguinte exemplo:

```javascript
// Primeira declaração da função `fun`
function fun (arg) {
    return arg;
}

// Segunda declaração da função `fun`. Vai sobrescrever a primeira
function fun (arg) {
    return arg ** 2; // Operador de potênciação. É equivalente a "arg * arg"
}
```

No código acima, a função "fun" é declarada duas vezes. Quando isso acontece, o JavaScript ignora a primeira declaração, e todas as chamadas posterioes à função "fun" se referenciarão à segunda declaração. Isso se deve porque a declaração de funções em JavaScript usa, internamente, o mesmo comportamento do `var`. O bloco acima é (aproximadamente) equivalente ao seguinte:

```javascript
var fun = function (arg) {
    return arg;
}

var fun = function (arg) {
    return arg ** 2;
}
```

Como no JavaScript é permitido declara a mesma variável duas vezes usando o `var`, esse código não gera erros, e a segunda declaração vai sobrescrever a primeira declaração. Muito raramente os desenvolvedores usam esse comportamento propositalmente, e ele quase sempre é a causa de um bug.

Com *Arrow Functions*, se for usado o `const` para declarar a variável que receberá a função, não será possível sobrescrever o valor antigo da função. Veja o seguinte exemplo:

```javascript
const fun = (arg) => {
    return arg;
}

// Aqui haverá um erro de syntaxe: a variável 'fun' já foi declarada.
const fun = (arg) => {
    return arg ** 2;
}
```

Assim, códigos que usam *Arrow Functions* são ligeiramente mais seguros.

## Atalhos de Arrow Functions

Há algumas formas mais curtas de declarar algumas *Arrow Functions* específicas.

### Apenas um argumento

Se a sua *Arrow Function* só recebe um argumento, pode-se emitir os parênteses da lista de argumentos, como por exemplo:

```javascript
// Arrow function usual
const fun = (arg) => { /* code */ }

// Com parênteses omitidos
const fun = arg => { /* code */ }
```

É sempre importante lembrar que isso só é possível se ela tiver **exatamente** um argumento. Para qualquer outro número de argumentos, são necessários parênteses.

### Apenas uma expressão de retorno

Se a sua *Arrow Function* só precisa retornar uma única operação (uma soma, subtração, ou chamada de função), você pode emitir as chaves e o `return` do bloco, como por exemplo:

```javascript
// Arrow Function usual
const fun = (a, b) => { return a + b; }

// Arrow Function com as chaves omitidas
const fun = (a, b) => a + b
```

As duas declarações acima são equivalentes. Sempre que as chaves de uma *Arrow Function* são omitidas, a expressão que estiver logo em seguida da flecha será o retorno da *Arrow Function*.

### Um argumento e uma expressão

É possível misturar os dois casos anteriores, caso a sua *Arrow Function* tenha exatamente um argumento e uma expressão de retorno, como por exemplo:

```javascript
// Arrow Function usual
const fun = (arg) => { return arg ** 2; }

// Arrow Function com parênteses e chaves omitidas
const fun = arg => arg ** 2
```

## Por que não usar Arrow Functions?

### A declaração das funções não é tão clara

O maior argumento contra o uso de `Arrow Functions` se refere à legibilidade. Para muitos, a declaração de uma *Arrow Function* não é tão evidente quanto a declaração de uma função usual. É argumentado que, como a declaração de uma *Arrow Function* normalmente começa com a declaração de uma variável (como "`const nomeDaFuncao =`"), é mais difícil de separar a declaração de uma variável normal da de uma *Arrow Function*. Em contraste, quando uma linha começa com a palavra "`function`", já é evidente que estamos declarando uma função usual, o que ajuda a ler códigos muito grandes.

### Não usa um nome

O fato de uma *Arrow Function* não usar um nome é tanto uma vantagem quanto um perigo. Veja o seguinte exemplo:

```javascript
// OBS: A função 'fetchFromServer' não será implementada aqui, mas
// ela essencialmente só busca informações de um servidor pela internet,
// e chama a callback passada como argumento com a resposta do servidor.

setInterval(() => {
  fetchFromServer((data) => {
    setTimeout(() => {
      console.log(data.message);
    }, data.time);
  });
}, 1000);
```

Aqui fica bastante clara uma das desvantagens de não ter nome explícito para as coisas: pior legibilidade. Agora veja esse mesmo código, mas com funções nomeadas:

```javascript
function setupAlarm (data) {
    function displayAlarmMessage () {
        console.log(data.message);
    }

    setTimeout(displayAlarmMessage, data.time);
}

function checkForNewAlarms () {
    fetchFromServer(setupAlarm);
}

setInterval(checkForNewAlarms, 1000);
```

Aqui fica muito mais evidente que esse código está relacionado à alarmes, e que esses alarmes são buscados de um servidor. É claro que existem muitas maneiras de se aumentar a legibilidade de um código, mas a simples atribuição de nomes é, em geral, suficiente.

## Resumo

Nesse capítulo vimos sobre *Arrow Functions*:

* O que são
* Por que usar
* Alguns atalhos
* Vantagens
* Desvantagens
