Obrigado pela explicação! Eu tenho uma dúvida referente a isso e acredito que você possa responder. Você precisa criar uma função de soma (igual a que você viu que eu fiz), de que forma você criaria, e por quê?

Tipo, se tivesse que usar a função mais de uma vez, criaria com function expression, ou não?

E se tivesse que usar ela somente uma vez, criaria com arrow function?

Depende do contexto, e também cai muito em preferência pessoal.

Tenho visto ultimamente uma tendência de usar arrow function pra "tudo". Talvez por isso muita gente, principalmente quem está começando, pense que é o único jeito de declarar funções (ou pior, que é o "certo" ou "melhor"). Sendo que o correto seria entender as diferenças entre as formas de declará-las, os prós e contras de cada uma, e aí decidir de acordo com cada contexto.

Não existe uma regra certa, e cada um vai ter a sua.

Em geral, se algo vai ser usado várias vezes, eu prefiro uma function tradicional.

Mas muitas vezes, quando a função é curta, e geralmente usada como callback, acabo usando arrow function mesmo. Por exemplo:

var array = [1, 2, 3];
var dobro = array.map(n => n * 2);

A função é tão curta e direta que não compensa criar uma function só pra isso (na minha opinião). A não ser que eu precisasse de algo que a arrow function não tem (as diferenças já foram explicadas aqui, não é só syntax sugar, tem casos em que faz diferença).

Mas se a função fosse muito grande, provavelmente eu iria optar por criá-la separadamente, para deixar o código mais claro (mesmo que ela seja usada apenas uma vez):

// Em vez disso:
array.map(n => {
    // 100 linhas de código
});

// Eu ia preferir isso:
function fazAlgo(n) {
    // 100 linhas de código
}

array.map(fazAlgo);

O mesmo vale para quando temos uma função que dentro dela tem outra função, que tem outra, etc:

fazAlgo(function() {
    // várias linhas de código...
    ...
    // função outraCoisa recebe outra função
    outraCoisa(function() {
        // várias linhas de código
        ...
        // outra função que recebe uma função
        eMaisOutraCoisa(function() {
            // várias linhas de código
        });
    });
});

Neste caso, talvez eu declarasse cada função separadamente, em vez de criá-las todas de uma vez em um grande emaranhado - potencialmente confuso - de código.


Outro caso, suponha que tenho uma função que muda a aparência de um elemento HTML:

function mudaAparencia(elemento, corFundo, fonte, borda, margem) {
    // muda o estilo do elemento
    elemento.style.backgroundColor = corFundo;
    // etc...
}

E temos um botão que ao ser clicado, muda para valores específicos:

button.addEventListener('click', () => mudaAparencia(div, 'red', 'Arial', '4px', '0 auto'));

Neste caso uma arrow function que chama a função com valores específicos é uma solução simples e rápida. Até daria para fazer algo como:

function mudaRedArial() {
    mudaAparencia(div, 'red', 'Arial', '4px', '0 auto');   
}
button.addEventListener('click', mudaRedArial);

Mas a princípio não compensa criar esta função extra (porém, acho que compensaria se ela fosse reutilizada várias vezes).


Enfim, não tem regra absoluta que serve para todos os casos. Se perguntar para outras pessoas, provavelmente elas terão opiniões diferentes.

Na prática, considerando esses detalhes que o colega comentou acima, você usa a que você achar melhor, porque faz pouquíssima diferença. Eu não sei se existe algum caso de uso em que só dá pra usar uma dessas opções, acredito que não. Eu uso exclusivamente arrow functions, até porque são syntactic sugar, ou seja, feitas pra facilitar a vida do programador. Quando você vai declarar uma função que só vai ser usada naquele caso específico, como como parâmetro de outra função, por exemplo, é bem mais prático e fácil de ler. Se você trabalha com React ou alguma outra biblioteca ou framework que são muito focadas em programação funcional, arrow functions acabam sendo basicamente o padrão.

O único caso de diferença real é em funções geradoras. Nesse caso, você precisa usar a palavra-chave function* com o asterisco depois. Não existe equivalente pra arrow functions. Mas funções geradoras cumprem objetivos bem específicos e são bem raras.