Meilleures pratiques pour les itérations en JavaScript

Meilleures pratiques pour les itérations en JavaScript

Cet article explique les meilleures pratiques pour les itérations en JavaScript.

YouTube Video

Meilleures pratiques pour les itérations en JavaScript

En JavaScript, il est courant d'utiliser des boucles for pour les itérations. Ici, nous fournirons une explication détaillée des meilleures pratiques pour utiliser les boucles for et écrire un code efficace et lisible.

Choisissez la bonne structure de boucle

JavaScript propose plusieurs types de boucles, chacune adaptée à des objectifs différents.

 1// Example of a for loop
 2for (let i = 0; i < 5; i++) {
 3    console.log(i);
 4}
 5
 6// Example of a for...of loop
 7const array = [10, 20, 30];
 8for (const value of array) {
 9    console.log(value);
10}
11
12// Example of a for...in loop
13const obj = { a: 1, b: 2, c: 3 };
14for (const key in obj) {
15    console.log(`${key}: ${obj[key]}`);
16}
17
18// Example of a while loop
19let count = 0;
20while (count < 5) {
21    console.log(count);
22    count++;
23}
  • L'instruction for est adaptée lorsque le nombre d'itérations est prédéterminé.
  • L'instruction for...of est adaptée pour traiter de manière concise des tableaux et des objets itérables.
  • L'instruction for...in est utilisée pour itérer sur les propriétés d'un objet. Cependant, elle n'est pas adaptée aux tableaux.
  • L'instruction while et l'instruction do...while sont utilisées pour contrôler des boucles basées sur des conditions.

Utilisation de la méthode forEach et de l'instruction for...of.

Lorsqu'on parcourt un tableau, il est courant d'utiliser une instruction for pour accéder à l'indice, mais la méthode forEach ou l'instruction for...of peuvent être plus lisibles.

 1// Using a standard for loop
 2const array = ["apple", "banana", "cherry"];
 3for (let i = 0; i < array.length; i++) {
 4    console.log(array[i]);
 5}
 6
 7// Using forEach
 8array.forEach(item => console.log(item));
 9
10// Using for...of
11for (const item of array) {
12    console.log(item);
13}
  • L'instruction for permet une gestion explicite des indices lors de l'itération.
  • La méthode forEach utilise une fonction de rappel pour traiter chaque élément de manière concise.
  • L'instruction for...of est très lisible et permet un accès direct à chaque élément d'un tableau.

Optimisez les conditions de boucle

Étant donné que la condition de boucle est évaluée de manière répétée, éviter les calculs inutiles peut améliorer les performances.

 1const names = ["Alice", "Bob", "Charlie"];
 2const scores = [85, 92, 78];
 3
 4// Inefficient example
 5for (let i = 0; i < Math.min(names.length, scores.length); i++) {
 6    console.log(`${names[i]} scored ${scores[i]}`);
 7}
 8
 9// Efficient example
10for (let i = 0, len = Math.min(names.length, scores.length); i < len; i++) {
11    console.log(`${names[i]} scored ${scores[i]}`);
12}
  • Comme indiqué dans cet exemple, stocker le résultat du calcul dans une variable au préalable permet une exécution de boucle plus efficace.
 1const scores = [85, 92, 78];
 2let sum = 0;
 3let sum2 = 0;
 4
 5// Inefficient example
 6for (let i = 0; i < scores.length; i++) {
 7    sum += scores[i];
 8}
 9console.log(`Total score : ${sum}`);
10
11// Efficient example
12for (let i = scores.length - 1; i >= 0; i--) {
13    sum2 += scores[i];
14}
15console.log(`Total score : ${sum2}`);
  • Comme indiqué dans cet exemple, inverser la condition peut parfois être plus efficace.

Optimisation du traitement des boucles

Comme le traitement des boucles est exécuté de manière répétée, éviter les calculs inutiles peut améliorer les performances.

 1const array = ["apple", "banana", "cherry"];
 2
 3// Inefficient example
 4for (let i = 0; i < 100; i++) {
 5    const element = document.querySelector("#myElement");
 6    element.textContent = `Count: ${i}`;
 7}
 8
 9// Efficient example
10const element = document.querySelector("#myElement");
11for (let i = 0; i < 100; i++) {
12    element.textContent = `Count: ${i}`;
13}
  • Dans cet exemple, en déplaçant la méthode querySelector à l'extérieur de la boucle, les calculs répétés inutiles sont éliminés.

Soyez conscient de la portée des variables

Utilisez let ou const pour garantir que les variables à l'intérieur de la boucle aient une portée appropriée. Comme var est limité à la portée des fonctions, cela peut entraîner un comportement inattendu.

 1// Using let
 2for (let i = 0; i < 3; i++) {
 3    console.log(i);
 4}
 5
 6// Potential issue with var
 7for (var i = 0; i < 3; i++) {
 8    setTimeout(() => console.log(i), 1000); // 3, 3, 3
 9}
10
11// Using let to avoid the issue
12for (let i = 0; i < 3; i++) {
13    setTimeout(() => console.log(i), 1000); // 0, 1, 2
14}
  • var a une portée de fonction, donc après la boucle, i est 3 et toutes les fonctions exécutées par setTimeout affichent 3.
  • Avec let, la variable i dans la fonction de rappel de setTimeout se réfère à une nouvelle valeur à chaque boucle, donc 0, 1, 2 sont affichés comme prévu.

Améliorez la lisibilité avec des sorties anticipées

Pour simplifier le traitement des boucles, utilisez break et continue de manière appropriée pour améliorer la lisibilité.

 1// Example using break
 2for (let i = 0; i < 10; i++) {
 3    if (i === 5) {
 4        break; // Exit the loop
 5    }
 6    console.log(i);
 7}
 8
 9// Example using continue
10for (let i = 0; i < 10; i++) {
11    if (i % 2 === 0) {
12        continue; // Skip to the next iteration
13    }
14    console.log(i);
15}
  • Utiliser break vous permet d'interrompre le traitement de la boucle à mi-chemin en sautant toutes les itérations suivantes.
  • Utiliser continue vous permet de passer le processus de boucle actuel et de passer à l'itération suivante.

Évitez l'imbrication profonde

Une imbrication profonde rend le code plus difficile à lire, alors essayez de limiter la profondeur avec des retours anticipés ou en divisant les fonctionnalités en fonctions.

 1// Deeply nested example
 2for (let i = 0; i < 5; i++) {
 3    for (let j = 0; j < 5; j++) {
 4        if (i + j > 5) {
 5            console.log(i, j);
 6        }
 7    }
 8}
 9
10// Improved using function decomposition
11function processPairs(i) {
12    for (let j = 0; j < 5; j++) {
13        if (i + j > 5) {
14            console.log(i, j);
15        }
16    }
17}
18
19for (let i = 0; i < 5; i++) {
20    processPairs(i);
21}
  • Dans cet exemple, des fonctions sont utilisées pour réduire l'imbrication.

Considérez la gestion des erreurs

S'il existe une possibilité d'erreurs dans la boucle, mettez en œuvre une gestion des erreurs appropriée.

 1const data = ["123", "abc", "456", "xyz"];
 2
 3// Without Error Handling
 4for (const item of data) {
 5    const result = parseInt(item);
 6    console.log(`Parsed value: ${result}`);
 7}
 8
 9// With Error Handling
10for (const item of data) {
11    try {
12        const result = parseInt(item);
13        if (isNaN(result)) {
14            throw new Error(`Invalid number: ${item}`);
15        }
16        console.log(`Parsed value: ${result}`);
17    } catch (error) {
18        console.error(`Error processing item: ${item}. ${error.message}`);
19    }
20}
  • Dans cet exemple, la gestion des erreurs est effectuée pour traiter les données invalides, détecter et signaler les problèmes.

Points à noter dans le traitement asynchrone

Lors de la gestion du traitement asynchrone dans les boucles, l'utilisation de async/await peut produire un code concis et intuitif.

 1const urls = ["https://example.com/1", "https://example.com/2"];
 2
 3// Proper handling of asynchronous operations
 4async function fetchUrls() {
 5    for (const url of urls) {
 6        const response = await fetch(url);
 7        const data = await response.json();
 8        console.log(data);
 9    }
10}
11
12fetchUrls();
  • Ce code récupère de manière asynchrone les URLs du tableau urls une par une et traite les résultats au format JSON. L'utilisation d'async/await simplifie les opérations asynchrones, récupérant séquentiellement les données pour chaque URL et les affichant dans la console.

Comprenez la différence entre l'instruction for...of et forEach() dans le traitement asynchrone.

 1async function asyncTask(num) {
 2    return new Promise(resolve => {
 3        setTimeout(() => {
 4            console.log(`Task ${num} done`);
 5            resolve();
 6        }, 100);
 7    });
 8}
 9
10async function runWithForOf() {
11    console.log("Start for...of");
12    for (const num of [1, 2, 3]) {
13        await asyncTask(num);
14    }
15    console.log("End for...of");
16}
17
18async function runWithForEach() {
19    console.log("Start forEach");
20    [1, 2, 3].forEach(async num => {
21        await asyncTask(num);
22    });
23    console.log("End forEach");
24}
25
26async function executeExamples() {
27    await runWithForOf();
28    await runWithForEach();
29}
30
31executeExamples();
  • Lors du traitement asynchrone dans les boucles, notez les différences de comportement, comme illustré dans cet exemple, entre l'utilisation de for...of avec async/await et l'utilisation de forEach().

  • Avec for...of, le code s'exécute de manière séquentielle et attend au niveau du await à l'intérieur de la boucle avant de continuer à l'itération suivante. En revanche, forEach() exécute le traitement en parallèle.

Conclusion

L'instruction for en JavaScript est un outil simple mais puissant. En exploitant les meilleures pratiques présentées ici, vous pouvez écrire un code efficace et hautement lisible. Faites attention à sélectionner des structures de boucle appropriées, à gérer la portée, à gérer les erreurs, et visez un code hautement maintenable.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video