Tenho uma opinião (que tenho certeza de que será compartilhada por alguns) de que a passagem de funções anônimas que contêm mais do que algumas linhas de código, como argumentos para outras funções, afeta drasticamente a legibilidade e a auto-documentação, a ponto de achar que seria será muito melhor para qualquer um que provavelmente use o código apenas para declarar uma função nomeada. Ou pelo menos atribua essa função anônima a uma variável antes de declarar a função principal
No entanto, muitas bibliotecas JavaScript (jQuery, d3.js / NVD3.js) apenas para dar alguns exemplos, usam grandes funções dessa maneira.
Por que isso é tão amplamente aceito em JavaScript? É algo cultural, ou há vantagens que estou perdendo, que tornariam o uso mais preferido do que declarar uma função nomeada?
fonte
public
eprivate
é uma solução alternativa por não ter um fechamento adequado.Respostas:
Três razões principais em que posso pensar:
Acesso ao escopo pai: as definições de função embutida permitem que o código embutido tenha acesso às variáveis definidas nos escopos pai. Isso pode ser muito útil para muitas coisas e pode reduzir a quantidade ou a complexidade do código, se feito corretamente.
Se você colocar o código em uma função definida fora deste escopo e depois chamar o código, precisará passar qualquer estado pai que ele deseje acessar para a função.
Privacidade: o código dentro de uma definição anônima embutida é mais privado e não pode ser chamado por outro código.
Redução de nomes definidos em escopos mais altos: isso é mais importante ao operar no escopo global, mas uma declaração anônima em linha impede que seja necessário definir um novo símbolo no escopo atual. Como o Javascript não exige nativamente o uso de espaços para nome, é aconselhável evitar definir mais símbolos globais do que o mínimo necessário.
Editorial: Parece ter se tornado algo cultural em Javascript, onde declarar algo anonimamente inline é considerado "melhor" do que definir uma função e chamá-la mesmo quando o acesso ao escopo pai não é usado. Suspeito que isso tenha ocorrido inicialmente devido ao problema global de poluição do namespace em Javascript e, talvez, devido a problemas de privacidade. Mas agora se transformou em algo cultural, e você pode vê-lo expresso em muitos órgãos públicos de código (como os mencionados).
Em linguagens como C ++, a maioria provavelmente consideraria uma prática abaixo do ideal ter uma função gigante que se estende por várias páginas / telas. Obviamente, o C ++ possui espaço para nome embutido, não fornece acesso ao escopo pai e possui recursos de privacidade, para que possa ser totalmente motivado pela legibilidade / manutenção, enquanto o Javascript deve usar a expressão de código para obter privacidade e acesso ao escopo pai. Assim, JS parece ter sido motivado em uma direção diferente e tornou-se algo cultural na linguagem, mesmo quando as coisas que motivaram essa direção não são necessárias em um caso específico.
fonte
Funções anônimas são usadas para muito mais propósitos em JavaScript do que na maioria dos idiomas.
Primeiro, eles são usados para espaçamento de nomes e escopo de bloco. Até recentemente, o JavaScript não possuía módulos ou qualquer outro tipo de mecanismo de namespacing, o que levou ao uso de funções anônimas para fornecer essa funcionalidade por meio do padrão de módulo. Não haveria absolutamente nenhum benefício em nomear essas funções. Em uma escala menor, devido à falta de escopo do bloco do JavaScript até recentemente, um padrão semelhante foi usado para imitar o escopo do bloco; mais notavelmente no corpo de loops. Usar uma função nomeada nesse caso seria ofuscantemente ativa.
Segundo, e menos específicas do JavaScript, as funções anônimas são frequentemente usadas com funções de ordem superior que imitam as estruturas de controle. Por exemplo, o
each
método do jQuery . Duvido que você abstraia cada corpo de loop ou se-ramifique em uma função sempre que tiver mais do que algumas linhas. A mesma lógica se aplica neste caso.Uma razão final é que a programação baseada em eventos é comum no JavaScript, o que tende a levar a um código de estilo de passagem de continuação inadvertido . Você faz uma chamada AJAX e registra um retorno de chamada que, quando executado, fará outra chamada AJAX e registra um retorno de chamada etc. Se as chamadas forem síncronas e não assíncronas, isso seria apenas uma sequência linear de código em um único escopo lexical . Novamente, duvido que você abstraia todas as poucas linhas de código linear em uma função.
Também existem fatores culturais e, pelas razões acima, entre outras, funções anônimas são muito mais comuns em JavaScript do que em muitos outros idiomas e são usadas mais confortavelmente / menos do que em muitos outros idiomas.
fonte