Javascript: funções anônimas vs nomeadas

Estou estudando sobre como deixar um códio mais legível e com a manutenção mais fácil e talvez passe a compartilhar alguns insights através de posts com vocês.

A legibiliade de um código é tão importante quanto a sua funcionalidade

Código ruim

Com certeza você já viu ou faz uso de funções anônimas passadas como callbacks dessa forma:

list.filter((item) => {
   return item % 2 == 0;
});

Problema

Você pode até saber o que significa item % 2 == 0 (significa que o número é par), mas você foi obrigado a ler o corpo da função para saber o que ela faz, ou por qual critério essa lista está sendo filtrada.

Esse exemplo é pequeno, de apenas uma linha, mas imagine isso para um código maior e mais complexo: Vai tomar tempo para entender

Solução

Uma solução óbvia, a princípio, seria deixar um comentário ali explicando. O problema é que um código todo comentado é detestável.

Imagine um comentário como um quebra-molas em uma pista. Não dá né?

O código deve falar por si só. Você é um autor, então escreva pensando no seu leitor.

list.filter(function isEven(item) {
   return item % 2 == 0;
});

(Even é par em inglês)

Bem melhor, né? Perceba que ao nomear a função, eu não precisa mais ler o seu corpo para saber o que ela faz. Isso me poupa tempo.

Isso não exclui o uso de funções anônimas. Para mim, elas devem ser usadas como uma forma de escopo, sem função própria pra abranger outras funções.

Por exemplo:

O useEffect do react recebe uma função como callback. Se sua função for simples e síncrona, você pode passar uma função nomeada diretamente. Mas se sua função for assíncrona, não vai funcionar fazer assim useEffect(async () => {}).

Esse é um caso onde usar a função nomeada atrapalharia a leitura, portanto acredito que um bom uso seria assim:

useEffect(() => {
    loadData();
    
    async function loadData() {
        const data = await fetchData();
    }
})

Acredito que isso possa contribuir para melhorar seus códigos. Abraço! Aproveitem para discordar ou complementar nos comentários 😄

Eu costumo a declarar ainda animas, mas da seguinte forma:

const nomeDaFuncao = (...args) => {
     console.log(args)
     //..... return bla bla bla
}

list.filter(nomeDaFuncao)

Quando tenho que exportar fica até fácil exportar a const, pois vou poder usa-la da mesma forma e ainda passar em outras callbacks

É uma forma de fazer também, explicitando o intuito da função. Porém tenha cuidado com o uso do this. Funções nomeadas e anônimas possuem um uso diferente do this. A grosso modo, enquanto as funções nomeadas possuem o contexto léxico do this de onde foram **chamadas**, as funções anônimas possuem o de onde foram **criadas**. Exemplo: ```javascript function fullName() { console.log(this.firstName + " " + this.lastName); } this.firstName = "Neymar" this.lastName = "Jr." const anonymFullName = () => { console.log(this.firstName + " " + this.lastName); } function sayPeopleName(fullNameFunc) { this.firstName = "Alberto" this.lastName = "Casagrande" fullNameFunc(); } sayPeopleName(fullName) sayPeopleName(anonymFullName) ``` Saída: ``` Alberto Casagrande Neymar Jr. ``` Perceba que a função `fullName` quando é chamada em `sayPeopleName` printa o nome "Alberto Casagrande", que é o nome no this de `sayPeopleName`, onde ela foi **chamada**. Já a função `anonymFullName` printa o nome "Neymar Jr.", que é o nome no contexto this que ela foi **criada**. Mesmo as funções nomeadas podem ser exportadas e passadas como callbacks da mesma forma. O seu exemplo é executável dessa forma também: ```javascript function nomeDaFuncao (...args) { console.log(args) //..... return bla bla bla } list.filter(nomeDaFuncao) ```
Eu entendo a eventloop e para onde o this encaminha, seja ele um metodo, função ou qualquer objeto de callback 😅 Eu particularmente contorno o uso de this, descoplando os elementos de uma class ppr exemplo. Sua explicação a respeito de escopo foi muito boa, poderia também ter dito a reapeiro dos binds, como a própria prototype bind, call e apply. 😌 Tornam uma confusão na mente de quem esta iniciando agora, mas na real é bem simples o uso. Oque mais vejo por ai são curry com bind mal formada e quebrando toda a estrutura por não entenderem o escopo 😅 Outro ponto da sua resposta, poderia ser dito sobre construtores e a própria prototype 🥰 a origem da sintex sugar "class". Obrigado por complementar a resposta, senti que faltou export mais detalhes técnicos da minha parte 🥰