Devo aninhar funções em idiomas que me permitam fazer isso ou devo evitá-lo?

12

Em JavaScript, PL / SQL e algumas outras linguagens, as funções podem ser aninhadas, ou seja, declaradas em outra função. Isso pode ser usado para dividir uma função grande em partes menores, mas mantenha essas partes dentro do contexto da função maior.

function doTooMuch() {
    function doSomething () {
       ...
    }
    function doSomethingElse() {
       ...
    }
    function doYetAnotherThing() {
       ...
    }

    // doTooMuch body

    doSomething();
    doSomethingElse();
    doYetAnotherThing();
}

Em alguns casos, quando essas funções menores não usam variáveis ​​locais da função maior, isso pode ser facilmente alterado para uma versão em que todas as funções não são aninhadas.

function doSomething () {
   ...
}
function doSomethingElse() {
   ...
}
function doYetAnotherThing() {
   ...
}
function doTooMuch() {
    doSomething();
    doSomethingElse();
    doYetAnotherThing();
}

Supondo que essas funções aninhadas não devam ser usadas em nenhum outro lugar, é melhor mantê-las no contexto da função grande ou é ruim porque é exatamente isso que torna a função grande, bem, grande?

user281377
fonte

Respostas:

8

É uma questão de opinião, mas eu evitaria funções de aninhamento, a menos que fosse realmente uma parte necessária e deliberada do seu design.

Quando você aninha funções, na maioria dos idiomas, você acaba com algum tipo de efeito mecânico. O mais comum e interessante é fechar o escopo lexical de uma variável que pode ser usada dentro do corpo, mas outras (por exemplo: visibilidade da função) também aparecem algumas vezes.

Essas são ferramentas tipicamente impressionantes, quando usadas corretamente - mas são ferramentas complexas, porque podem resultar em efeitos não locais ou não óbvios quando você olha o código pela primeira vez.

Se você não usá-los, muitas pessoas lerão o código e não verão nada - o que pressupõe que eles não o entenderam e olharão novamente, tentando descobrir por que você fez dessa maneira e não em um escopo separado.

Você também corre o risco de futuros programadores fecharem deliberada ou acidentalmente algo que não pretendiam, não percebendo o risco ali.

Finalmente, se a sua declaração de função declara uma função nomeada fora do escopo da função envolvente, evite-a. Isso é super confuso para todos.

Quanto à nota final: porque o código de funções individuais ajuda delimitar, funções de nidificação é menos problemático do que uma única função gigante, mas em última análise, faz média leitura de um código muito mais para entender doTooMuch()- especialmente se você pode esconder código entre as declarações de função aninhados, ou precisa verificar se ninguém fez.

Daniel Pittman
fonte
-1: Javascript não é "a maioria dos idiomas". Aninhar funções em Javascript é uma prática normal.
Kevin cline
2
@kevincline funções de nidificação em JavaScript é uma prática comum ruim
Raynos
@ Raynos: Se você não aninhar, onde você vai colocá-los? Não há classes para contê-los. Aqui está um código típico:jquery(function($){ $('#id').click(function(){...}); }
kevin Cline
@kevincline ... Código típico para noobs, você precisa de funções aninhadas em profundidade. E isso porque o javascript não tem escopo de módulo, então você precisa desse fechamento anônimo.
Raynos
E se esse clique executar uma chamada Ajax, com um retorno de chamada de conclusão? Agora você tem funções aninhadas em dois níveis. Claro, você pode limitar o aninhamento atribuindo os fechamentos anônimos às variáveis. Isso é realmente melhor?
Kevin cline #
2

Essa é uma daquelas perguntas que não têm resposta certa e palavras como "preferência pessoal", "prática em equipe" vêm à mente. Na minha opinião, pequenas funções (agora, aqui está outra coisa subjetiva) que não são usadas em nenhum lugar pertencem às suas funções-pai, especialmente quando podem ser sem nome.

devmiles.com
fonte
0

Esta pergunta não tem resposta certa, porque nenhuma das opções maximiza o encapsulamento. Se você os aninhar, eles ainda terão acesso a variáveis ​​que não deveriam. Caso contrário, outras funções terão acesso a funções que não deveriam. De qualquer maneira, você perde.

DeadMG
fonte