[PT-BR] Afinal, qual é a diferença entre arrow functions e funções regulares?
Tags: javascript, frontend, beginners, programming
Published: 2023-07-19 02:35:37

Às vezes, de tanto usarmos um padrão, acabamos nos esquecendo do real motivo pelo qual escrevemos nosso código dessa maneira. Minha intenção neste conteúdo é lembrar você (ou mostrar pela primeira vez) as principais diferenças entre uma função "regular" e uma arrow function.

Começando pelo princípio... O que é uma função mesmo?


## O que é uma função?

Eu chamaria uma função de um "mini programa". Nada mais é do que um trecho de código criado para um determinado fim. A sintaxe é bem simples; para isso, você precisa usar a palavra `function`.

Aqui está um exemplo de uma função que imprime no console um "Olá Mundo!”

```jsx
function helloWorld () {
	console.log('Olá Mundo!')
}
```

Certo, agora que estamos todos na mesma página, vamos ao que interessa!


## O que é uma arrow function?

A partir do [ES6](https://www.w3schools.com/js/js_es6.asp), uma nova possibilidade de sintaxe foi introduzida no JavaScript, 
chamada "arrow function". Ela nos permite, entre outras coisas, escrever um código reduzido, sem a necessidade de utilizar a palavra `function`.

Para obter o mesmo resultado do exemplo de código anterior usando arrow function, teríamos o seguinte código:

```jsx
const helloWorld = () => console.log('Olá Mundo!')
```

Porém, além da diferença na sintaxe, existem outras diferenças que quero apresentar a você. São as principais delas, às quais se deve estar atento para não ter problemas indesejados.


## Principais diferenças


### Contexto

As arrow functions possuem um `this` dinâmico, ou seja, "seu próprio `this`". Já as funções regulares herdam o contexto de onde foram declaradas. Deixe-me ilustrar para esclarecer a explicação:

```jsx
const testfunction = {
  number: 42,
  func: function() {
    return this.number
  }
}
console.log(testfunction.func())
// Output: 42

const testArrowFunction = {
  number: 42,
  func: () =>  {
    return this.number
  }
}
console.log(testArrowFunction.func())
// Output: undefined
```

No caso da função regular, ela absorve o contexto de sua declaração e, nesse caso, reconhece a propriedade "number". Já a arrow function, como "cria seu próprio this", procura dentro de si mesma a propriedade "number" e, como não encontra, seu retorno é `undefined`.


### Construtor

As arrow functions não podem ser `constructors`, não é possível fazer uma chamada usando o operador new:

```jsx
const regular = function() {}
const arrowfunction = () => {}

new regular() // safe...
new arrowfunction() // Error: arrowfunction is not a constructor
```

### Arguments

Ainda devido ao contexto léxico, as arrow functions não têm acesso ao `arguments`. Um exemplo:

```jsx
function regular() {
  return arguments
}
console.log(regular('batata', 'arroz')) // { 0: 'batata', 1: 'arroz' }

const arrowFunction = () => {
  return arguments
}
console.log(arrowFunction('batata', 'arroz')) //{ 0:f, 1: window, ... }
```

As arrow functions não têm `arguments`. Elas têm acesso ao `arguments` da função “regular” pai mais próxima.


### Retorno

As arrow functions lhe dão a possibilidade de fazer um retorno encurtado
 sem a necessidade explícita da utilização da palavra reservada `return`.

```jsx
// exemplo 1
function regular () {
  return [1, 2, 3]
}

const arrowFunction = () => [1, 2, 3]

// exemplo 2
function regularObj () {
  return { foo: 1 }
}

const arrowFunctionObj = () => ({ foo: 1 })
```

### Hoisting

O JavaScript adiciona declarações de funções "regulares" na memória antes da execução de qualquer trecho do código. Isso permite que você use a função antes de sua declaração. Com uma arrow function, isso não é possível, já que elas são anônimas e atribuídas a uma variável. Portanto, essa alocação antes da execução do código não acontece. Veja o exemplo:

```jsx
console.log(regular()) // 'regular function'

function regular () {
  return 'regular function'
}

console.log(arrowFunction()) // Error: Cannot access 'arrowFunction' before initialization

const arrowFunction = () => 'arrow function'
```

Para que o mesmo código funcione corretamente, seria necessário alterar a ordem da declaração da arrow function da seguinte maneira:

```jsx
const arrowFunction = () => 'arrow function'
console.log(arrowFunction()) // 'arrow function'
```


## Conclusão

Bom, espero ter esclarecido sua mente em relação ao uso das arrow functions no JavaScript. Às vezes, nos esquecemos das diferenças no uso das funções e podemos perder várias horas debugando erros em nosso código, tudo por descuido ou em busca de uma sintaxe simplificada.

Esteja atento aos pontos apresentados e bora codar!!!