54 votes

Boucle For au lieu de while

En parcourant la source jQuery, je suis tombé sur le code suivant (disponible ici ):

 for (; i < length;) {
    if (callback.apply(object[i++], args) === false) {
        break;
    }
}
 

Pourquoi une boucle for est-elle utilisée ici au lieu d'une boucle while ?

44voto

aroth Points 28424

Je vote pour quelqu'un ayant une affinité pour le mauvais style de codage. C'est la seule explication que je peux voir pour l' for boucle et de l' i++ être placées à l'intérieur d'un indice de tableau. Je pense que ce serait mieux:

while (i < length && callback.apply(object[i], args)) {
    i++;
}

Ou s'il vous arrive de sentir que l' === de l'opérateur dans l'exemple original a de la valeur, puis:

while (i < length && callback.apply(object[i], args) !== false) {
    i++;
}

Une autre raison possible pour faire ce qui peut avoir été comme une optimisation des performances. Bien que ce guide de référence que j'ai mis en place semble infirmer cette théorie. Sur Windows, l' while boucle ci-dessus est 20% plus rapide que l'original for boucle dans google Chrome, IE et Firefox deux boucles à effectuer la même. Sur OS X le for boucle a un avantage de 10% dans Firefox, il n'y a pas de différence entre les deux dans Chrome, et Safari préfère l' while boucle de 6%.

Donc, à partir d'un point de vue des performances, c'est un lavage. Si rien, alors à en juger par la part de marché, vous auriez probablement souhaitez optimiser pour google Chrome sur Windows avant de les optimiser pour Firefox sur Mac, auquel cas l' while boucle serait préférable.

Qui me dit qu'il est peu probable que l'optimisation de la performance joué un facteur avec ce code. Et je retourne à ma théorie originale que c'est juste un exemple de mauvais style de codage fait passé le code du processus d'examen.

26voto

Stephen Swensen Points 13439

Probablement parce qu'elle a été "refactorisée" à partir d'une boucle for (x in obj) : http://james.padolsey.com/jquery/#v=1.3.2&fn=jQuery.each

21voto

hammar Points 89293

Voici le commit qui a introduit cette bizarrerie .

Message de validation:

jquery core: réduction du code à $.each et $.curCSS .

Snip du diff:

 -        for ( var i = 0, length = object.length; i < length; i++ )
-          if ( callback.apply( object[ i ], args ) === false )
+        for ( ; i < length; )
+          if ( callback.apply( object[ i++ ], args ) === false )
 

Il semblerait que l'auteur ait simplement manqué l'occasion de changer les for en while .

6voto

Briguy37 Points 4748

Tout d'abord, il n'y a jamais une longueur de coûts pour l'utilisation d'un for boucle sur un while boucle, mais vous pouvez obtenir des fonctionnalités supplémentaires avec l' for boucle, de sorte que certains codeurs juste de toujours utiliser l' for:

for(;<condition>;){}
while(<condition>){}

Cela dit, je pense que le but, ici, peut-être pour des raisons de cohérence avec le reste du code.

Par exemple, voici une partie du code d'origine. Comme vous pouvez le voir, dans ce code, vous pouvez rester dans la boucle "for" mode de penser tout le temps, de sorte qu'il se sent de plus en plus cohérentes:

if (args) {
    if (isObj) {
        for (name in object) {
            if (callback.apply(object[name], args) === false) {
                break;
            }
        }
    } else {
        for (; i < length;) {
            if (callback.apply(object[i++], args) === false) {
                break;
            }
        }
    }
}

Comparez cela à le remplacement de la deuxième boucle avec un while. Lorsque vous la lecture de ce code, vous devez l'activer à partir de la boucle "for" le mode de pensée de la boucle "while" mode de pensée. Maintenant, je ne sais pas pour vous, mais je la trouve un peu plus rapide pour mes yeux, pour basculer entre la boucle conditions ci-dessus, par opposition à la boucle conditions ci-dessous. C'est parce que dans le cas ci-dessus, je peut juste se concentrer sur les conditions, alors que dans le cas ci-dessous, mes yeux sont attirés à relire l' while et de la for à chaque fois parce qu'ils sont différents:

if (args) {
    if (isObj) {
        for (name in object) {
            if (callback.apply(object[name], args) === false) {
                break;
            }
        }
    } else {
        while (i < length) {
            if (callback.apply(object[i++], args) === false) {
                break;
            }
        }
    }
}

2voto

cmpolis Points 2358

J'ai constaté que de telles choses se produisaient lorsque je les réécrivais ou si plusieurs personnes touchaient un morceau de code. Ne peut pas voir une raison particulière pour cela.

J'espère que je suis initialisé correctement au-dessus de ce bloc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X