Dois-je imbriquer des fonctions dans des langages qui me permettent de le faire ou dois-je plutôt l'éviter?

12

En JavaScript, PL / SQL et certains autres langages, les fonctions peuvent être imbriquées, c'est-à-dire déclarées dans une autre fonction. Cela pourrait être utilisé pour diviser une grande fonction en morceaux plus petits, mais garder ces morceaux dans le contexte de la fonction plus grande.

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

    // doTooMuch body

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

Dans certains cas, lorsque ces fonctions plus petites n'utilisent pas de variables locales de la fonction plus grande, cela pourrait facilement être changé en une version où toutes les fonctions ne sont pas imbriquées.

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

En supposant que ces fonctions imbriquées ne doivent pas être utilisées ailleurs, est-il préférable de les conserver dans le contexte de la grande fonction ou est-ce mauvais parce que c'est exactement ce qui rend la grande fonction, eh bien, grande?

user281377
la source

Réponses:

8

C'est une question d'opinion, mais j'éviterais les fonctions d'imbrication à moins que ce ne soit en fait une partie nécessaire et délibérée de votre conception.

Lorsque vous imbriquez des fonctions, dans la plupart des langues, vous vous retrouvez avec une sorte d'effet mécanique. La plus courante, et intéressante, est de fermer la portée lexicale d'une variable qui peut être utilisée à l'intérieur du corps, mais d'autres (par exemple: visibilité de la fonction) apparaissent également une partie du temps.

Ce sont généralement des outils impressionnants, lorsqu'ils sont utilisés correctement - mais ce sont des outils complexes, car ils peuvent entraîner des effets non locaux ou non évidents lorsque vous jetez un coup d'œil au code.

Si vous ne les utilisez pas, beaucoup de gens liront le code et ne verront rien faire cela - supposons donc qu'ils l'ont manqué, et regardent à nouveau, essayant de comprendre pourquoi vous l'avez fait de cette façon, et non dans une portée distincte.

Vous risquez également que les futurs programmeurs clôturent délibérément ou même accidentellement quelque chose qu'ils n'avaient pas l'intention de faire, en ne remarquant pas le risque immédiatement.

Enfin, si votre déclaration de fonction déclare une fonction nommée en dehors de la portée de la fonction englobante, évitez-la. C'est super déroutant pour tout le monde.

Quant à la note finale: parce que les différentes fonctions de l' aide code délimitent, les fonctions de nidification est moins gênant qu'une seule fonction géante, mais finalement il ne moyenne la lecture d' un code beaucoup plus à comprendre doTooMuch()- surtout si vous pouvez cacher le code entre les déclarations de fonctions imbriquées, ou besoin de vérifier que personne ne l'a fait.

Daniel Pittman
la source
-1: Javascript n'est pas "la plupart des langues". L'imbrication de fonctions en Javascript est une pratique normale.
kevin cline
2
Les fonctions d'imbrication de @kevincline en JavaScript sont une mauvaise pratique courante
Raynos
@Raynos: Si vous ne les imbriquez pas, où allez-vous les mettre? Il n'y a aucune classe pour les contenir. Voici un code typique:jquery(function($){ $('#id').click(function(){...}); }
kevin cline
@kevincline ... Code typique pour les noobs, vous avez besoin de fonctions imbriquées en profondeur. Et c'est parce que javascript n'a pas de portée de module, vous avez donc besoin de cette fermeture anonyme.
Raynos
Et si ce clic exécute un appel Ajax, avec un rappel de fin? Vous disposez maintenant de fonctions imbriquées sur deux niveaux. Bien sûr, vous pouvez limiter l'imbrication en affectant les fermetures anonymes aux variables. Est-ce vraiment mieux?
kevin Cline
2

C'est une de ces questions qui n'ont pas de bonne réponse et des mots comme "préférence personnelle", "pratique d'équipe" viennent à l'esprit. À mon avis, les petites fonctions (maintenant voici une autre chose subjective) qui ne sont utilisées nulle part appartiennent à leurs fonctions parentales, surtout lorsqu'elles peuvent être sans nom.

devmiles.com
la source
0

Cette question n'a pas de bonne réponse, car aucun des deux choix ne maximise l'encapsulation. Si vous les imbriquez, ils ont toujours accès à des variables qu'ils ne devraient pas. Si vous ne le faites pas, alors d'autres fonctions ont accès à des fonctions qu'elles ne devraient pas. De toute façon, vous perdez.

DeadMG
la source