Migliori pratiche per i cicli for in TypeScript

Migliori pratiche per i cicli for in TypeScript

Questo articolo spiega le migliori pratiche per utilizzare i cicli for in TypeScript.

YouTube Video

Migliori pratiche per i cicli for in TypeScript

Le istruzioni for sono una sintassi fondamentale e potente per eseguire operazioni ripetitive. In TypeScript, sfruttare la sicurezza dei tipi e scrivere codice tenendo a mente leggibilità e manutenibilità ti permette di scrivere codice efficiente con meno errori.

Scegliere il tipo di ciclo giusto

TypeScript offre diversi costrutti di ciclo, ciascuno adatto a casi d'uso differenti. Scegliere il ciclo appropriato è cruciale per la chiarezza e le prestazioni del codice.

Ciclo for standard

1for (let i = 0; i < 10; i++) {
2    console.log(i);
3}

Il ciclo standard for è ideale quando è necessario un controllo preciso sull'indice di iterazione.

Migliori pratiche
1const maxIterations = 10;
2for (let i = 0; i < maxIterations; i++) {
3    console.log(i);
4}

Quando scrivi istruzioni for, tenere a mente i seguenti punti può aiutarti a scrivere codice più sicuro e leggibile.

  • Usa let per le variabili di indice
    • Usare let invece di var limita l'ambito al blocco, prevenendo comportamenti indesiderati.
  • Usa costanti e nomi di variabili descrittivi per rendere espliciti i limiti del ciclo.
    • Evitare numeri magici e usare nomi di variabili significativi migliora la leggibilità.

Ciclo for...of

1const array = [1, 2, 3];
2for (let value of array) {
3    console.log(value);
4}

Il ciclo for...of è adatto per iterare su oggetti iterabili come array e stringhe.

Migliori pratiche
1const array = [1, 2, 3];
2for (const value of array) {
3    console.log(value);
4}

Quando scrivi cicli for...of, prestare attenzione ai seguenti punti può aiutarti a scrivere codice più sicuro.

  • Usa const per le variabili del ciclo
    • Se i valori non vengono modificati all'interno del ciclo, usare const aiuta a prevenire riassegnazioni accidentali.

Ciclo for...in

1const obj = { a: 1, b: 2, c: 3 };
2for (const key in obj) {
3    console.log(`${key}: ${obj[key]}`);
4}

Il ciclo for...in itera sulle proprietà enumerabili di un oggetto.

Migliori pratiche
1const obj = { a: 1, b: 2, c: 3 };
2for (const key in obj) {
3    if (obj.hasOwnProperty(key)) {
4        console.log(`${key}: ${obj[key]}`);
5    }
6}

Quando scrivi un ciclo for...in, puoi considerare i seguenti punti.

  • Filtra le proprietà
    • Se devi evitare proprietà ereditate, puoi usare hasOwnProperty.
  • Non usare for...in con gli array. Evita di utilizzare for...in con le matrici. Potrebbe iterare su tutte le proprietà enumerabili, inclusi quelli che non sono indici di matrice.

Metodo forEach

1const array = [1, 2, 3];
2array.forEach((value, index) => {
3    console.log(`Index: ${index}, Value: ${value}`);
4});

Durante l'iterazione su array, forEach è conciso ed elimina la necessità di gestire gli indici.

Migliori pratiche

Quando usi il metodo forEach, puoi considerare i seguenti punti.

  • Usa le funzioni freccia
    • Usa funzioni freccia concise per migliorare la leggibilità.
  • Evita interruzioni
    • forEach non supporta break o continue. Usa i cicli for...of o for quando necessario:.

Sicurezza dei Tipi e Prevenzione degli Errori

Sfruttando il sistema di tipi di TypeScript, puoi prevenire errori a runtime durante l'iterazione:.

Definisci Tipi Rigorosi per le Variabili nei Cicli

1const items = [1, 2, 3];
2items.forEach(item => {
3    console.log(item * 2);
4});
1const items: number[] = [1, 2, 3];
2items.forEach((item: number) => {
3    console.log(item * 2);
4});

Specificando esplicitamente i tipi per le variabili del ciclo, puoi rilevare errori di tipo in anticipo.

Evita Impliciti any

1{
2  "compilerOptions": {
3    "noImplicitAny": true
4  }
5}

Inoltre, abilitando noImplicitAny in tsconfig.json, è possibile impedire che le variabili senza tipi espliciti vengano assegnate implicitamente al tipo any.

Usa ReadonlyArray Quando Necessario

1const numbers: ReadonlyArray<number> = [1, 2, 3];
2for (const value of numbers) {
3    console.log(value);
4}

Se stai iterando su un array che non dovrebbe essere modificato, puoi usare ReadonlyArray.

Considerazioni sulle Prestazioni

L'efficienza è cruciale per i cicli che elaborano grandi dataset o cicli eseguiti frequentemente:.

Scegli il metodo di implementazione del ciclo ottimale.

Esistono vari modi per implementare i cicli, ognuno con differenze in termini di leggibilità ed efficienza di esecuzione.

 1// Prepare input data (an array from 1 to 1000000)
 2const input: number[] = Array.from({ length: 1000000 }, (_, i) => i + 1);
 3
 4// --- for ---
 5console.time('for loop');
 6const squaresFor: number[] = [];
 7for (let i = 0; i < input.length; i++) {
 8    squaresFor.push(input[i] * input[i]);
 9}
10console.timeEnd('for loop');
11
12// --- while ---
13console.time('while loop');
14const squaresWhile: number[] = [];
15let i: number = 0;
16while (i < input.length) {
17    squaresWhile.push(input[i] * input[i]);
18    i++;
19}
20console.timeEnd('while loop');
21
22// --- for-of ---
23console.time('for-of loop');
24const squaresForOf: number[] = [];
25for (const num of input) {
26    squaresForOf.push(num * num);
27}
28console.timeEnd('for-of loop');
29
30// --- forEach ---
31console.time('forEach loop');
32const squaresForEach: number[] = [];
33input.forEach((num: number): void => {
34    squaresForEach.push(num * num);
35});
36console.timeEnd('forEach loop');
37
38// --- map ---
39console.time('map');
40const squaresMap: number[] = input.map((value: number): number => value * value);
41console.timeEnd('map');

L'efficienza varia a seconda dell'ambiente di esecuzione, ma ad esempio, quando si esegue un ciclo un milione di volte, la differenza può diventare piuttosto evidente. Scegli il metodo ottimale per il ciclo considerando la manutenibilità e le prestazioni.

Usa Metodi di Iterazione Nativi

 1const squares = [1, 2, 3].map(value => value * value);
 2console.log(squares);
 3
 4const numbers = [1, 2, 3, 4, 5, 6];
 5const evenNumbers = numbers.filter(value => value % 2 === 0);
 6console.log(evenNumbers); // [2, 4, 6]
 7
 8const squaredEvens = numbers
 9    .filter(value => value % 2 === 0) // Keep only even numbers
10    .map(value => value * value);     // Square the remaining values
11
12console.log(squaredEvens); // [4, 16, 36]

Metodi come map e filter possono essere più leggibili in alcuni casi.

Preferisci for...of per Maggiore Leggibilità

Le prestazioni dovrebbero essere prioritarie solo in casi limitati; generalmente è più importante scrivere codice leggibile. Ad esempio, dare priorità a for...of può migliorare la leggibilità.

1const fruits = ["apple", "banana", "cherry"];
2
3for (let i = 0; i < fruits.length; i++) {
4    console.log(`${i}: ${fruits[i]}`);
5}
Migliori pratiche
1const fruits = ["apple", "banana", "cherry"];
2
3for (const [index, fruit] of fruits.entries()) {
4    console.log(`${index}: ${fruit}`);
5}

Dando priorità ai cicli for...of, puoi scrivere codice più leggibile e resistente agli errori. Come mostrato in questo esempio, se hai bisogno anche degli indici degli array, combinare entries() con for...of è efficace.

Evitare le Trappole Comuni

Modificare Collezioni Durante l'Iterazione

1const array = [1, 2, 3];
2for (const value of [...array]) {
3    if (value === 2) {
4        array.push(4); // Avoid this!
5    }
6}
7console.log(array);

Modificare un array durante l'iterazione può portare a comportamenti imprevisti:. Usa una copia se necessario.

Considera i casi limite

1const array: number[] = [];
2for (const value of array) {
3    console.log(value); // No output, but no errors
4}

Questo codice funziona bene, ma se hai bisogno di gestire array vuoti, puoi migliorarlo come segue.

1const array: number[] = [];
2if (array.length === 0) {
3    console.log("The array is empty.");
4} else {
5    for (const value of array) {
6        console.log(value);
7    }
8}

Considerare i casi limite può aiutare a prevenire errori nel codice successivo.

Conclusione

Per padroneggiare l'istruzione for in TypeScript, è essenziale comprendere le varie strutture di ciclo, aderire a pratiche sicure per i tipi e ottimizzare le performance. Queste best practice ti aiutano a scrivere codice più pulito, affidabile e manutenibile.

Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.

YouTube Video