Mejores prácticas para los bucles for en TypeScript

Mejores prácticas para los bucles for en TypeScript

Este artículo explica las mejores prácticas para usar los bucles for en TypeScript.

YouTube Video

Mejores prácticas para los bucles for en TypeScript

Las declaraciones for son una sintaxis fundamental y poderosa para realizar operaciones repetitivas. En TypeScript, aprovechar la seguridad de tipos y escribir código teniendo en cuenta la legibilidad y el mantenimiento te permite escribir código eficiente con menos errores.

Elegir el tipo de bucle adecuado

TypeScript ofrece varias estructuras de bucles, cada una adecuada para diferentes casos de uso. Elegir el bucle apropiado es crucial para la claridad del código y el rendimiento.

Bucle estándar for

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

El bucle estándar for es ideal cuando necesitas un control preciso sobre el índice de iteración.

Mejores Prácticas
1const maxIterations = 10;
2for (let i = 0; i < maxIterations; i++) {
3    console.log(i);
4}

Al escribir declaraciones for, tener en cuenta los siguientes puntos puede ayudarte a escribir un código más seguro y legible.

  • Usa let para las variables de índice
    • Usar let en lugar de var limita el alcance al bloque, lo que previene comportamientos no deseados.
  • Usa constantes y nombres descriptivos para las variables para hacer explícitos los límites del bucle.
    • Evitar números mágicos y usar nombres significativos para las variables mejora la legibilidad.

Bucle for...of

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

El bucle for...of es adecuado para iterar sobre objetos iterables como arreglos y cadenas.

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

Al escribir bucles for...of, prestar atención a los siguientes puntos puede ayudarte a escribir un código más seguro.

  • Usa const para las variables del bucle
    • Si los valores no se modifican dentro del bucle, usar const ayuda a prevenir reasignaciones accidentales.

Bucle for...in

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

El bucle for...in itera sobre las propiedades enumerables de un objeto.

Mejores Prácticas
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}

Al escribir un bucle for...in, puede considerar los siguientes puntos.

  • Filtra propiedades
    • Si necesitas evitar propiedades heredadas, puedes usar hasOwnProperty.
  • No uses for...in con arreglos Evita usar for...in con arrays. Podría iterar sobre todas las propiedades enumerables, incluyendo aquellas que no son índices de arrays.

Método forEach

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

Al iterar sobre arreglos, forEach es conciso y elimina la necesidad de gestionar índices.

Mejores Prácticas

Al usar el método forEach, puede considerar los siguientes puntos.

  • Usa funciones flecha
    • Usa funciones flecha concisas para mejorar la legibilidad.
  • Evita interrupciones
    • forEach no soporta break ni continue. Usa bucles for...of o for cuando sea necesario:.

Seguridad de Tipos y Prevención de Errores

Aprovechando el sistema de tipos de TypeScript, puedes prevenir errores en tiempo de ejecución durante la iteración:.

Define Tipos Estrictos para las Variables del Bucle

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});

Especificar explícitamente los tipos para las variables del bucle te permite detectar desajustes de tipos de forma temprana.

Evita el any Implícito

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

Además, al activar noImplicitAny en tsconfig.json, puedes evitar que las variables sin tipos explícitos se asignen implícitamente al tipo any.

Usa ReadonlyArray Cuando Sea Necesario

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

Si estás iterando sobre un array que no debería modificarse, puedes usar ReadonlyArray.

Consideraciones de Rendimiento

La eficiencia es crucial para bucles que procesan grandes conjuntos de datos o se ejecutan con frecuencia:.

Elige el método de implementación de bucle óptimo.

Existen varias formas de implementar bucles, cada una con diferencias en legibilidad y eficiencia de ejecución.

 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');

La eficiencia varía según el entorno de ejecución, pero, por ejemplo, al ejecutar un bucle un millón de veces, la diferencia puede volverse bastante notable. Elige el método de bucle óptimo considerando la mantenibilidad y el rendimiento.

Usa Métodos de Iteración Nativos

 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]

Métodos como map y filter pueden ser más legibles en ciertos casos.

Prefiere for...of para Mayor Legibilidad

El rendimiento debe priorizarse solo en casos limitados; en general, escribir código legible es más importante. Por ejemplo, priorizar el uso de for...of puede mejorar la legibilidad.

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

Al priorizar los bucles for...of, puedes escribir un código más legible y resistente a errores. Como se muestra en este ejemplo, si también necesitas índices de arreglos, combinar entries() con for...of es efectivo.

Evitando Errores Comunes

Modificar Colecciones Durante la Iteración

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);

Modificar un arreglo durante la iteración puede llevar a un comportamiento inesperado:. Usa una copia si es necesario.

Considera casos extremos

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

Este código funciona bien, pero si necesitas manejar arrays vacíos, puedes mejorarlo de la siguiente manera.

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}

Considerar casos extremos puede ayudar a prevenir errores en el código posterior.

Conclusión

Para dominar la declaración for en TypeScript, es esencial comprender varias estructuras de bucles, seguir prácticas seguras de tipos y optimizar el rendimiento. Estas mejores prácticas le ayudan a escribir un código más limpio, confiable y fácil de mantener.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video