Beste praktijken voor iteraties in JavaScript

Beste praktijken voor iteraties in JavaScript

Dit artikel legt de beste praktijken voor iteraties in JavaScript uit.

YouTube Video

Beste praktijken voor iteraties in JavaScript

In JavaScript is het gebruikelijk om for-lussen te gebruiken voor iteraties. Hier geven we een gedetailleerde uitleg over de beste praktijken voor het gebruik van for-lussen om efficiënte en leesbare code te schrijven.

Kies de juiste lusstructuur

JavaScript biedt meerdere lusconstructies, die elk geschikt zijn voor verschillende doeleinden.

 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}
  • for-verklaring is geschikt wanneer het aantal iteraties vooraf is bepaald.
  • for...of-verklaring is geschikt voor het beknopt verwerken van arrays en iterabele objecten.
  • for...in-verklaring wordt gebruikt om over de eigenschappen van een object te itereren. Echter, het is niet geschikt voor arrays.
  • while-verklaring en do...while-verklaring worden gebruikt om lussen op basis van voorwaarden te sturen.

Het gebruik van de forEach-methode en de for...of-verklaring

Bij het itereren door een array is het gebruikelijk om een for-verklaring te gebruiken om toegang tot de index te krijgen, maar de forEach-methode of de for...of-verklaring kan leesbaarder zijn.

 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}
  • for-verklaring maakt expliciet indexbeheer mogelijk tijdens het itereren.
  • forEach-methode maakt gebruik van een callbackfunctie om elk element beknopt te verwerken.
  • for...of-verklaring is zeer leesbaar en staat directe toegang toe tot elk element in een array.

Optimaliseer luscondities

Omdat de lusconditie herhaaldelijk wordt geëvalueerd, kan het vermijden van onnodige berekeningen de prestaties verbeteren.

 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}
  • Zoals in dit voorbeeld getoond, maakt het opslaan van het berekeningsresultaat in een variabele voorafgaand aan de uitvoering van de lus efficiënter.
 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}`);
  • Zoals in dit voorbeeld getoond, kan het omkeren van de conditie soms efficiënter zijn.

Het optimaliseren van lusverwerking

Aangezien lusverwerking herhaaldelijk wordt uitgevoerd, kan het vermijden van onnodige berekeningen de prestaties verbeteren.

 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}
  • In dit voorbeeld worden onnodige herhaalde berekeningen geëlimineerd door de querySelector-methode buiten de lus te verplaatsen.

Wees je bewust van scope

Gebruik let of const om te zorgen dat variabelen binnen de lus de juiste scope hebben. Aangezien var beperkt is tot functie-scope, kan het onverwacht gedrag veroorzaken.

 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 heeft een functionele scope, dus na de lus is i gelijk aan 3, en alle functies uitgevoerd door setTimeout geven 3 als resultaat.
  • Bij gebruik van let verwijst de i binnen de setTimeout-callback naar een nieuwe waarde voor elke lus, waardoor 0, 1, 2 als verwacht worden uitgegeven.

Verbeter de leesbaarheid met vroege exits

Gebruik break en continue op de juiste manier om de verwerking van lussen te vereenvoudigen en de leesbaarheid te verbeteren.

 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}
  • Met break kunt u de lusverwerking halverwege beëindigen en alle volgende iteraties overslaan.
  • Met continue kunt u het huidige lusproces overslaan en doorgaan naar de volgende iteratie.

Vermijd diepe nesting

Diepe nesting maakt code moeilijker leesbaar. Probeer de nesting oppervlakkig te houden door vroege returns te gebruiken of functionaliteit op te splitsen in functies.

 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}
  • In dit voorbeeld worden functies gebruikt om inspringingen te verminderen.

Overweeg foutafhandeling

Als er een mogelijkheid is dat fouten optreden binnen de lus, implementeer dan een goede foutafhandeling.

 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}
  • In dit voorbeeld wordt foutafhandeling uitgevoerd bij het verwerken van ongeldige gegevens, waarbij problemen worden gedetecteerd en gerapporteerd.

Belangrijke punten bij asynchrone verwerking

Bij het omgaan met asynchrone verwerking in lussen kan het gebruik van async/await resulteren in beknopte en intuïtieve code.

 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();
  • Deze code haalt asynchroon URL's op uit de urls-array één voor één en verwerkt de resultaten in JSON-formaat. Met async/await worden asynchrone bewerkingen vereenvoudigd, waarbij gegevens sequentieel worden opgehaald voor elke URL en worden uitgegeven naar de console.

Begrijp het verschil tussen de for...of instructie en forEach() bij asynchrone verwerking.

 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();
  • Bij het omgaan met asynchrone verwerking in lussen, let op de verschillende gedragspatronen, zoals weergegeven in dit voorbeeld, tussen het gebruik van for...of met async/await en het gebruik van forEach().

  • Met for...of wordt de code sequentieel uitgevoerd en wacht het op de await binnen de lus voordat het doorgaat naar de volgende iteratie. Aan de andere kant voert forEach() de verwerking parallel uit.

Conclusie

De for-instructie in JavaScript is een eenvoudige maar krachtige tool. Door gebruik te maken van de hier geïntroduceerde best practices kun je efficiënte en zeer leesbare code schrijven. Let op het kiezen van geschikte lusconstructies, scopebeheer, foutafhandeling en streef naar zeer onderhoudbare code.

Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.

YouTube Video