Executando verificação de segurança...
2

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 😄

Carregando publicação patrocinada...
1

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

1

É 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:

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:

function nomeDaFuncao (...args) {
     console.log(args)
     //..... return bla bla bla
}

list.filter(nomeDaFuncao)
1

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 🥰