Melhores Práticas para Loops 'for' no TypeScript

Melhores Práticas para Loops 'for' no TypeScript

Este artigo explica as melhores práticas para o uso de loops 'for' no TypeScript.

YouTube Video

Melhores Práticas para Loops 'for' no TypeScript

As declarações for são uma sintaxe fundamental e poderosa para realizar operações repetitivas. No TypeScript, aproveitar a segurança de tipos e escrever código com foco na legibilidade e manutenção permite que você escreva código eficiente com menos erros.

Escolhendo o Tipo de Loop Adequado

O TypeScript oferece várias construções de loops, cada uma adequada para diferentes casos de uso. Escolher o loop apropriado é crucial para a clareza do código e para o desempenho.

Loop for Padrão

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

O loop padrão for é ideal quando você precisa de controle preciso sobre o índice de iteração.

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

Ao escrever declarações for, manter os seguintes pontos em mente pode ajudar a escrever um código mais seguro e legível.

  • Use let para variáveis de índice
    • Usar let em vez de var limita o escopo ao bloco, prevenindo comportamentos indesejados.
  • Use constantes e nomes de variáveis descritivos para tornar os limites do loop explícitos.
    • Evitar números mágicos e usar nomes de variáveis significativos melhora a legibilidade.

Loop for...of

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

O loop for...of é adequado para iterar sobre objetos iteráveis, como arrays e strings.

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

Ao escrever loops for...of, prestar atenção aos seguintes pontos pode ajudá-lo a escrever um código mais seguro.

  • Use const para variáveis de loop
    • Se os valores não forem modificados dentro do loop, usar const ajuda a evitar reatribuições acidentais.

Loop for...in

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

O loop for...in itera sobre as propriedades enumeráveis de um objeto.

Melhores Práticas
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}

Ao escrever um loop for...in, você pode considerar os seguintes pontos.

  • Filtre propriedades
    • Se você precisar evitar propriedades herdadas, pode usar hasOwnProperty.
  • Não use for...in com arrays. Evite usar for...in com arrays. Isso pode iterar sobre todas as propriedades enumeráveis, incluindo as que não são índices de arrays.

Método forEach

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

Ao iterar sobre arrays, forEach é conciso e elimina a necessidade de gerenciar índices.

Melhores Práticas

Ao usar o método forEach, você pode considerar os seguintes pontos.

  • Use funções de seta (arrow functions)
    • Use funções de seta concisas para melhorar a legibilidade.
  • Evite interrupções
    • forEach não suporta break ou continue. Use laços for...of ou for quando necessário:.

Segurança de Tipos e Prevenção de Erros

Aproveitando o sistema de tipos do TypeScript, você pode prevenir erros em tempo de execução durante a iteração:.

Defina Tipos Estritos para Variáveis de Laço

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

Ao especificar explicitamente os tipos para as variáveis do loop, você pode detectar incompatibilidades de tipo precocemente.

Evite any Implícito

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

Além disso, ao habilitar noImplicitAny em tsconfig.json, você pode impedir que variáveis sem tipos explícitos sejam implicitamente atribuídas ao tipo any.

Use ReadonlyArray Quando Necessário

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

Se você estiver iterando sobre uma matriz que não deve ser modificada, pode usar ReadonlyArray.

Considerações de Desempenho

A eficiência é crucial para laços que processam grandes conjuntos de dados ou são executados frequentemente:.

Escolha o método ideal de implementação de loop.

Existem várias maneiras de implementar loops, cada uma com diferenças em legibilidade e eficiência de execução.

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

A eficiência varia dependendo do ambiente de execução, mas, por exemplo, ao executar um loop um milhão de vezes, a diferença pode se tornar bastante perceptível. Escolha o método de loop ideal considerando a manutenção e o desempenho.

Use Métodos de Iteração 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 e filter podem ser mais legíveis em alguns casos.

Prefira for...of pela Legibilidade

O desempenho deve ser priorizado apenas em casos limitados; escrever um código legível é, geralmente, mais importante. Por exemplo, priorizar for...of pode melhorar a legibilidade.

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

Ao priorizar loops for...of, você pode escrever um código mais legível e resistente a erros. Como mostrado neste exemplo, se você também precisar de índices de array, combinar entries() com for...of é eficaz.

Evitando Armadilhas Comuns

Modificar Coleções Durante a Iteração

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 um array durante a iteração pode levar a comportamentos inesperados:. Use uma cópia, se necessário.

Considere casos extremos

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

Este código funciona bem, mas se você precisar lidar com matrizes vazias, poderá melhorá-lo da seguinte forma.

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 pode ajudar a evitar erros no código subsequente.

Conclusão

Para dominar a declaração for no TypeScript, é essencial entender os vários construtos de loop, aderir a práticas seguras para tipos e otimizar o desempenho. Essas melhores práticas ajudam você a escrever códigos mais limpos, confiáveis e fáceis de manter.

Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.

YouTube Video