web-dev-qa-db-fra.com

Pourquoi les instructions "continuer" sont-elles mauvaises en JavaScript?

Dans le livre Javascript: The Good Parts de Douglas Crockford, voici tout ce que l'auteur a à dire sur la déclaration continue:

L'instruction continue saute en haut de la boucle. Je n'ai jamais vu un morceau de code qui n'a pas été amélioré en le refactorisant pour supprimer l'instruction continue.

Cela m'embrouille vraiment. Je sais que Crockford a des opinions très avisées sur JavaScript, mais cela me semble tout à fait faux.

Tout d'abord, continue fait plus que simplement sauter en haut d'une boucle. Par défaut, il progresse également vers l'itération suivante. La déclaration de Crockford n'est-elle donc pas simplement une fausse information?

Plus important encore, je ne comprends pas entièrement pourquoi continue serait même considéré comme mauvais. Ce post fournit ce qui semble être l'hypothèse générale: Pourquoi continuer à l'intérieur d'une boucle est-il une mauvaise idée?

Bien que je comprenne comment continue peut rendre le code difficile à lire dans certains cas, je pense qu'il est tout aussi probable qu'il puisse rendre le code plus lisible. Par exemple:

var someArray=['blah',5,'stuff',7];
for(var i=0;i<someArray.length;i++){
    if(typeof someArray[i]==='number'){
        for(var j=0;j<someArray[i];j++){
            console.log(j);
        }
    }
}

Cela pourrait être refactorisé en:

var someArray=['blah',5,'stuff',7];
for(var i=0;i<someArray.length;i++){
    if(typeof someArray[i]!=='number'){
        continue;
    }
    for(var j=0;j<someArray[i];j++){
        console.log(j);
    }
}

continue n'est pas particulièrement bénéfique dans cet exemple spécifique, mais il démontre le fait qu'il réduit la profondeur d'imbrication. Dans un code plus complexe, cela pourrait potentiellement augmenter la lisibilité.

Crockford ne fournit aucune explication quant à la raison pour laquelle continue ne devrait pas être utilisé, donc y a-t-il une signification plus profonde derrière cette opinion qui me manque?

62
twiz

La déclaration est ridicule. continue peut être utilisé abusivement, mais souvent aide lisibilité.

Utilisation typique:

for (somecondition)
{
    if (!firsttest) continue;

    some_provisional_work_that_is_almost_always_needed();

    if (!further_tests()) continue;

    do_expensive_operation();
}

Le but est d'éviter le code "lasagne", où vous avez des conditions profondément imbriquées.

Modifié pour ajouter:

Oui, c'est finalement subjectif. Voici ma métrique pour décider.

Modifié une dernière fois:

Cet exemple est bien sûr trop simple et vous pouvez toujours remplacer les conditions imbriquées par des appels de fonction. Mais vous devrez peut-être ensuite transmettre des données aux fonctions imbriquées par référence, ce qui peut créer des problèmes de refactorisation au moins aussi graves que ceux que vous essayez d'éviter.

71
egrunin

Je suis personnellement de l'autre côté que la majorité ici. Le problème n'est généralement pas avec les modèles continue affichés, mais avec ceux plus profondément imbriqués, où les chemins de code possibles peuvent devenir difficiles à voir.

Mais même votre exemple avec un continue ne montre pas d'amélioration à mon avis qui est justifiable. D'après mon expérience, quelques instructions continue sont un cauchemar pour refactoriser plus tard (même pour les langages statiques mieux adaptés pour une refactorisation automatisée comme Java, en particulier lorsque quelqu'un y met plus tard break aussi).

J'ajouterais donc un commentaire à la citation que vous avez donnée:

Refactoring pour supprimer l'instruction continue augmente votre capacité de refactoriser.

Et les boucles intérieures sont vraiment bien candidates, par exemple fonction d'extraction . Un tel refactoring est effectué lorsque la boucle interne devient complexe, puis continue peut la rendre douloureuse.

Ce sont mes opinions honnêtes après avoir travaillé professionnellement sur des projets JavaScript en équipe, il y a des règles dont Douglas Crockford parle montrent vraiment leurs mérites.

8
jJ'

Douglas Crockford peut ressentir cela, car il ne croit pas à l'affectation dans un conditionnel. En fait, son programme JSlint ne vous permet même pas de le faire, même si Javascript le fait. Il n'écrirait jamais:

exemple 1

while (rec = getrec())
{   
    if (condition1(rec))
        continue;

    doSomething(rec);
}

mais je suppose qu'il écrirait quelque chose comme:

exemple 2

rec = getrec();

while (rec)
{   
    if (!condition(rec))
        doSomething(rec);

    rec = getrec();
}

Les deux fonctionnent, mais si vous mélangez accidentellement ces styles, vous obtenez une boucle infinie:

exemple

rec = getrec();

while (rec)
{   
    if (condition1(rec))
        continue;

    rec = getrec();
}

Cela pourrait expliquer pourquoi il n'aime pas continuer.

6
Tom Lucas

Continue est un outil extrêmement utile pour enregistrer les cycles de calcul dans les algorithmes. Bien sûr, il peut être mal utilisé, mais il en va de même pour tous les autres mots clés ou approches. Lors de la recherche de performances, il peut être utile d'adopter une approche inverse de la divergence de chemin avec une instruction conditionnelle. Une poursuite peut faciliter l'inverse en permettant de sauter des chemins moins efficaces lorsque cela est possible.

2
Travis J

En fait, d'après toutes les analyses, il semble:

  1. Si vous avez des boucles peu profondes - n'hésitez pas à utiliser continuer si cela améliore la lisibilité (également il peut y avoir quelques gains de performances?).
  2. Si vous avez des boucles imbriquées profondes (ce qui signifie que vous avez déjà une boule de poils à démêler lorsque vous re-factorisez), éviter de continuer peut s'avérer bénéfique du point de vue de la fiabilité du code.

À la défense de Douglas Crokford, je pense que ses recommandations ont tendance à tendre vers programmation défensive , ce qui, en toute honnêteté, semble être une bonne approche pour `` protéger les idiots '' du code dans l'entreprise.

2
shauryashaurya

Personnellement, je n'ai jamais rien entendu de mal à propos de l'utilisation de la déclaration continue. Il est vrai que cela pourrait (la plupart du temps) être facilement évité, mais il n'y a aucune raison de pas l'utiliser. Je trouve que les boucles peuvent être beaucoup plus propres et plus lisibles avec des instructions continues en place.

1
Brock B.