Efficacité Javascript: 'for' vs 'forEach' [fermé]

103

Quelle est la norme actuelle en 2017 en Javascript avec des boucles for () vs un .forEach.

Je travaille actuellement mon chemin à travers Colt Steeles « Web Dev Bootcamp » sur Udemy et il privilégie forEachplus fordans ses enseignements. J'ai cependant recherché diverses choses pendant les exercices dans le cadre du travail de cours et je trouve de plus en plus de recommandations pour utiliser un for-loop plutôt que forEach. La plupart des gens semblent dire que la boucle for est plus efficace.

Est-ce quelque chose qui a changé depuis la rédaction du cours (vers 2015) ou sont-ils vraiment leurs avantages et inconvénients pour chacun, que l'on apprendra avec plus d'expérience.

Tout avis serait grandement apprécié.

tonyrobbins
la source
11
Pourquoi vous attacher à l'idée subjective de quelqu'un d'une norme de 2017? Adoptez une norme intemporelle, comme l'écriture de code propre et maintenable, sachant que les ingénieurs travaillent dur pour rendre les constructions les plus couramment utilisées très efficaces, puis optimisez les performances lorsque vous avez un problème de performance spécifique
2
Un natif forest difficile à battre pour la vitesse pure. forEach()invoque un rappel pour chaque itération; donc, cela entraîne évidemment des frais généraux.
canon du
1
étant un développeur que j'utilise à peine pour ou pour chacun, la plupart du travail est effectué par des méthodes de cartographie, de filtrage ou de réduction.
AT
12
@AT tant que vous ne faites pas partie de ces types qui utilisent mapuniquement pour l'itération et rejettent le nouveau tableau qu'il génère. Je ne sais pas combien de personnes j'ai dû corriger sur ce choix de fonction particulier sur ce site uniquement.
canon
1
@canon est d'accord, la sélection de boucle est importante et il faut garder à l'esprit la sortie et les résidus de ces méthodes lors du choix. Je crois que pour la lisibilité, les "boucles for" doivent être évitées.
AT

Réponses:

201

pour

forles boucles sont beaucoup plus efficaces. Il s'agit d'une construction en boucle spécialement conçue pour itérer alors qu'une condition est vraie , tout en offrant un mécanisme de progression (généralement pour augmenter l'itérateur). Exemple:

for (var i=0, n=arr.length; i < n; ++i ) {
   ...
}

Cela ne veut pas dire que for -loops sera toujours plus efficace, mais simplement que les moteurs et navigateurs JS les ont optimisés pour l'être. Au fil des ans, il y a eu des compromis sur la construction de boucle la plus efficace (pour, pendant, réduire, inverser, etc.) - différents navigateurs et moteurs JS ont leurs propres implémentations qui offrent différentes méthodologies pour produire les mêmes résultats. À mesure que les navigateurs s'optimisent davantage pour répondre aux exigences de performances, ils [].forEachpourraient théoriquement être implémentés de manière à être plus rapide ou comparable à un fichier for.

Avantages:

  • efficace
  • terminaison anticipée de la boucle (honneurs breaket continue)
  • contrôle de condition ( i<npeut être n'importe quoi et non lié à la taille d'un tableau)
  • portée variable ( var ilaisse idisponible après la fin de la boucle)

pour chaque

.forEachsont des méthodes qui itèrent principalement sur des tableaux (également sur d'autres énumérables, tels que des objets Mapet Set). Ils sont plus récents et fournissent un code subjectivement plus facile à lire. Exemple:

[].forEach((val, index)=>{
   ...
});

Avantages:

  • n'implique pas de configuration de variable (itère sur chaque élément du tableau)
  • functions / arrow-functions scope the variable to the block
    Dans l'exemple ci-dessus, valserait un paramètre de la fonction nouvellement créée. Ainsi, toutes les variables appelées valavant la boucle conserveraient leurs valeurs après sa fin.
  • subjectivement plus maintenable car il peut être plus facile d'identifier ce que fait le code - il itère sur un énumérable; alors qu'une boucle for pourrait être utilisée pour n'importe quel nombre de schémas de boucle

Performance

La performance est un sujet délicat, qui nécessite généralement une certaine expérience en matière de prévoyance ou d'approche. Afin de déterminer à l'avance (pendant le développement) le niveau d'optimisation requis, un programmeur doit avoir une bonne idée de l'expérience passée avec le cas problématique, ainsi qu'une bonne compréhension des solutions potentielles.

L'utilisation de jQuery dans certains cas peut parfois être trop lente (un développeur expérimenté peut le savoir), alors que d'autres fois peuvent être un non-problème, auquel cas la conformité entre les navigateurs de la bibliothèque et la facilité d'exécution d'autres fonctions (par exemple, AJAX, gestion des événements) vaudrait le temps de développement (et de maintenance) économisé.

Un autre exemple est que si les performances et l'optimisation étaient tout, il n'y aurait pas d'autre code que la machine ou l'assemblage. De toute évidence, ce n'est pas le cas car il existe de nombreux langages de haut niveau et de bas niveau, chacun avec ses propres compromis. Ces compromis incluent, mais ne sont pas limités à la spécialisation, la facilité et la vitesse de développement, la facilité et la vitesse de maintenance, le code optimisé, le code sans erreur, etc.

Approche

Si vous ne savez pas si quelque chose nécessitera un code optimisé, il est généralement préférable d'écrire d'abord du code maintenable. À partir de là, vous pouvez tester et identifier ce qui nécessite plus d'attention lorsque cela est nécessaire.

Cela dit, certaines optimisations évidentes devraient faire partie de la pratique générale et ne nécessiter aucune réflexion. Par exemple, considérez la boucle suivante:

for (var i=0; i < arr.length; ++i ){}

Pour chaque itération de la boucle, JavaScript récupère les arr.lengthopérations de coût de recherche de clé à chaque cycle. Il n'y a aucune raison pour que cela ne soit pas:

for (var i=0, n=arr.length; i < n; ++i){}

Cela fait la même chose, mais ne récupère arr.lengthqu'une seule fois, en mettant la variable en cache et en optimisant votre code.

vol7ron
la source
25
Réponse excellente, approfondie et non présomptueuse, non liée à un seul point dans le temps, à une mise en œuvre ou à un test de micro-référence.
1
Parfait, c'est exactement ce que je recherchais et donne beaucoup plus de profondeur que la vidéo ne le pourrait. J'apprécie vraiment cela, étant nouveau, il y a tellement à apprendre et ce sont les choses qu'il est facile de sauter en favorisant simplement l'un par rapport à l'autre sans raison qui pourrait vous gêner à l'avenir. Merci beaucoup!
tonyrobbins
2
for-loop ont souvent un avantage en termes de débogage: ils sont triviaux pour entrer, casser et inspecter. Avec forEach (), le niveau de rappel supplémentaire peut compliquer un peu les choses.
Eric Grange
1
@FelipeBuccioni merci, j'allais en fait examiner cela car je pense que les moteurs vérifient maintenant si un tableau serait muté pour déterminer si la longueur est mise en cache. Cependant, à des fins héritées, je pense que les moteurs d'optimisation n'étaient pas aussi généreux et que la longueur était un problème de performance à chaque itération. Je vais jeter un oeil à votre article et l'intégrer dans la réponse quand j'aurai le temps, ou j'espère qu'un membre exceptionnel de la communauté apportera un amendement comme une modification pour moi :)
vol7ron
6
J'apprécie vraiment l'explication dans cette réponse et la phrase [...], if performance and optimization was everything, there would be no other code than machine or assembly.. Je crois qu'avec la letdéclaration de déclaration d'une variable locale de portée de bloc, le deuxième avantage de forEachn'est plus un avantage sur la forboucle, sauf dans un environnement sans prise en charge de let.
user7393973