Artigo original: https://www.freecodecamp.org/news/master-the-art-of-looping-in-javascript-with-these-incredible-tricks-a5da1aa1d6c5/

Escrito por: Yogi

Muitas vezes em seu código, você precisa percorrer um array de números, strings ou objetos. Existem muitas maneiras de se fazer isso. Este tutorial tem como objetivo ensinar todas elas para que você se torne um mestre em "laços de repetição em JavaScript".

1. O laço for

O laço for é a maneira mais básica de fazer um laço em seu código em JavaScript. É muito útil executar um bloco de código várias vezes. Ele usa um contador, cujo valor é inicializado primeiro e, em seguida, seu valor final é especificado.

O contador é aumentado em um valor específico toda vez que o laço é executado. O laço for verifica se o contador está dentro dos limites (entre o valor inicial e o valor final) e termina quando o valor do contador ultrapassa o valor final.

Mostrarei aqui alguns exemplos.

a. Percorrendo um array

No código abaixo, estou percorrendo todos os números em um array e imprimindo cada um deles na janela do console.

var numeros = [10, 20, 30, 40, 50];
for (var i = 0; i < numeros.length; i++) {
    console.log(numeros[i]);
}

Da mesma forma, você também pode percorrer arrays de strings.

b. Percorrendo elementos do DOM

Imagine que você deseja localizar e colorir de vermelho todas as âncoras na página. Então, aqui, você também pode usar o laço for, assim:

var elementos = document.querySelectorAll("a");
for (var i= 0; i < elementos.length; i++) {
    elementos[i].style.color = "red";
}

Explicação: Primeiro, eu peguei todas as âncoras em um array usando document.querySelectorAll("a"). Depois, eu os percorri e mudei a cor deles para vermelho.

No site da W3Schools, eu executei o código acima no console do navegador e veja o que aconteceu:

1_QNXWEhb8zst1xFsYJAD2pg
Alterando a cor de todos os elementos de âncora para vermelho

Observação: o jQuery também tem um método muito bom de repetição, o método Each (texto em inglês), que auxilia a percorrer arrays, objetos, elementos do DOM, JSON e XML com facilidade. Se estiver usando o  jQuery no seu site, considere usá-lo ao fazer um laço de repetição.

2. O laço "For In"

O laço for in é usado para percorrer as propriedades de um objeto/array sem usar um 'contador'. Portanto, é uma versão simplificada do laço for.

O bloco de código dentro do laço será executado uma vez para cada propriedade.

a. Percorrendo as propriedades de um objeto

Tenho um objeto que contém algumas propriedades e usarei o laço for in para pesquisar cada propriedade e seu valor.

O código abaixo imprime todas as propriedades e seus valores na janela do console.

var pessoa = { fname: "Nick", lname: "Jonas", age: 26 };
for (var x in pessoa) {
    console.log(x + ": " + pessoa[x])
}
1_hcxLefNPQ0RsJn0GBskJEw
Percorrendo as propriedades de um objeto com um laço for in em JavaScript

b. Percorrendo dados em JSON

JSON é um formato muito popular para transmitir objetos de dados que consistem em pares atributo-valor e tipos de dados de array. Os sites usam JSON para compartilhar suas informações com sites externos. Agora, mostrarei como extrair dados de um JSON.

Imagine que eu tenha algum JSON contendo algumas informações, conforme mostrado abaixo:

jsonData: {
um: [11, 12, 13, 14, 15],
dois: [21, 22, 23],
tres: [31, 32]
}

O JSON tem um nó raiz chamado 'jsonData'. Ele contém 3 nós – 'um', 'dois', 'tres'. Os nós também são chamados de chaves.

O código abaixo mostra como extrair informações do JSON usando o laço for in:

var json = {
jsonData: {
um: [11, 12, 13, 14, 15],
dois: [21, 22, 23],
tres: [31, 32]
}
};

for (var key in json.jsonData) {
    for (var key1 in json.jsonData[key]) {
        console.log(json.jsonData[key][key1])
    }
}

Explicação: Existem 2 laços for in no código acima - o laço externo e o interno.

O laço externo é executado 3 vezes e cobre os nós 'um', 'dois' e 'tres'.

O laço interno abrange todos os valores dentro do node selecionado, ou seja, os valores dentro dos arrays 'um', 'dois' e 'tres'.

Execute o código na sua página web ou na janela do console do seu navegador, e você verá todos os valores dos nós impressos, como na imagem abaixo:

1_7SRGhCXNeuVVdwa_cOaLAw
Laço for in em JSON

Indo um pouco mais fundo no JSON

O mesmo JSON pode ser expresso colocando [] para conter os 3 nós:

jsonData: [{
um: [11, 12, 13, 14, 15]
}, {
dois: [21, 22, 23]
}, {
tres: [31, 32]
}]

Agora, vou usar uma combinação de laços for e for in para extrair todas as informações deste JSON. O código abaixo faz isso funcionar:

var json = {
jsonData: [{
um: [11, 12, 13, 14, 15]
}, {
dois: [21, 22, 23]
}, {
thes: [31, 32]
}]
};

for (var i = 0; i < json.jsonData.length; i++) {
    for (var key in json.jsonData[i]) {
        for (var j = 0; j < json.jsonData[i][key].length; j++) {
            console.log(json.jsonData[i][key][j])
        }
    }
}

3. O laço "while"

O laço while tem uma condição especificada nele. Ele verifica a condição e executa o bloco de código enquanto a condição for verdadeira. Observe que o laço while não possui um contador como o laço for.

a. Percorrendo um elemento de tabela HTML

Suponha que eu tenha uma tabela HTML que mostre os preços de diferentes produtos. Essa tabela HTML se assemelha a da imagem abaixo:

1_DKlO7m_UNsS57xCPwALDkQ
Tabela de preços sem o total dos produtos

Você pode ver que esta tabela não mostra o preço total dos produtos. Portanto, se houver um requisito para você mostrar o preço total, você deverá percorrer todos os preços e mostrar o total no rodapé da tabela. É assim que você vai fazer.

Adicione o código da tabela HTML à sua página da web:

<table id="priceTable">
    <tr>
        <th>Id</th>
        <th>Nome do produto</th>
        <th>Preço do produto</th>
    </tr>
    <tr> 
        <td>1</td>
        <td>Camisas</td>
        <td>49.99</td>
    </tr>
    <tr>
        <td>2</td>
        <td>Calças</td>
        <td>55.50</td>
    </tr>
    <tr> 
        <td>3</td>
        <td>Meias</td>
        <td>20</td>
    </tr>
    <tr>
        <td>4</td>
        <td>Calçados</td>
        <td>99</td>
    </tr>
    <tr>
        <td>5</td>
        <td>Jaquetas</td>
        <td>88.90</td>
    </tr>
</table>

Depois, adicione o CSS para dar um design adequado à tabela em html:

<style>
    #priceTable {
       font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
       border-collapse: collapse;
       width: 100%;
    }

        #priceTable td, #priceTable th {
            border: 1px solid #ddd;
            padding: 8px;
        }

        #priceTable tr {
            background-color: #f2f2f2;
        }

        #priceTable th {
            padding-top: 12px;
            padding-bottom: 12px;
            text-align: left;
            background-color: #4CAF50;
            color: white;
        }
</style>

Agora, percorra a tabela com o laço while e calcule a soma de todos os produtos. Adicione o código JavaScript abaixo à sua página da web que faz isso funcionar:

var table = document.getElementById("priceTable");

var i = 1;
var soma = 0;
while (i < table.rows.length) {
    soma += parseFloat(table.rows[i].cells[2].innerHTML)
    i++;
}

var row = table.insertRow(i);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);

cell2.innerHTML = "Preço Total";
cell3.innerHTML = soma;

Explicação: Primeiro, eu pego a referência da tabela usando var table = document.getElementById("priceTable"). Adicionei 2 variáveis ​​chamadas 'i' e 'soma'. A variável 'i' é a variável condicional do laço while, enquanto 'soma' continuará adicionando o preço de cada produto a ela.

Ao executar o laço while para o valor da variável 'i' de 1 a (total de linhas -1). Isso pega o total de linhas na tabela por table.rows.length e adiciona à condição do laço while:

while (i < table.rows.length) {
  //…
}

Observação: A tabela tem 6 linhas, do índice 0 ao 5, e cada linha tem 3 colunas, do índice 0 ao 2. Eu executei especificamente o laço do valor da variável 'i' de 1 e não 0. Isso ocorre porque no índice 0 da linha na tabela está o nome da coluna (de que eu não preciso).

Dentro do laço while, continuei adicionando os valores do preço de cada produto à variável soma assim: soma += parseFloat(table.rows[i].cells[2].innerHTML) e, no final, aumentei o valor de 'i ' por 1.

Por exemplo, quando o valor 'i' é 1, então table.rows[1] me dá a primeira linha (primeiro elemento 'tr'). Da mesma forma, table.rows[1].cells[2] fornecerá o valor da coluna de preço (elemento preço 'td') da primeira linha.

Quando o laço termina, adiciono uma nova linha à tabela no final. Dentro desta linha, estou adicionando as 3 colunas — 0º índice, 1º índice e 2º índice. Por fim, estou mostrando a string 'total' na 1ª coluna e o preço total contido na variável 'soma' na 2ª coluna.

O código que faz a adição desta nova linha é:

var row = table.insertRow(i);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);

cell2.innerHTML = "Total Price";
cell3.innerHTML = soma;

O table.insertRow(i) adicionará uma 6ª linha porque o valor da variável 'i' é 6 no momento em que o laço while termina.

As colunas (elemento 'td') são adicionadas a esta nova linha por row.insertCell(0), row.insertCell(1), row.insertCell(2).

Eu mostro um valor dentro da coluna por:

cell2.innerHTML = "Total Price";
cell3.innerHTML = soma;

O código JavaScript acima criará uma nova linha contendo o preço total do produto. Agora a tabela ficará assim:

1_JJruezS2_0bal7nO9xFFSw
Tabela de preços com o total dos produtos

b.  Loop infinito


Abaixo está o loop infinito na instrução While:

var infiVal = true;

while (infiVal) {
  // seu código
}

Observação: loops infinitos podem travar o navegador, portanto, é necessário executar o laço em um intervalo de alguns milissegundos. Você pode usar o método do JavaScript setInterval para executar uma determinada função a cada 1.000 milissegundos. Veja o código abaixo:

var myVar = setInterval(myTimer, 1000);

function myTimer() {
  // seu código
}

4. O laço "do while"

No laço do while, a condição a ser verificada é fornecida no final e, portanto, o laço é executado pelo menos uma vez, mesmo que a condição não seja verdadeira. Veja o código abaixo que dará uma mensagem 'Olá' na caixa de alerta, mesmo que a condição seja falsa desde o início (pois o valor da variável 'i' é sempre maior que 1).

var i = 2;

do {
    alert("Olá");
    i++;
}
while (i < 1);

a. Percorrendo o XML

Agora usarei o laço do while para saber como percorrer o XML e extrair dados dele. Eu tenho um arquivo XML chamado 'XMLFile1.xml' com esse conteúdo:

<?xml version="1.0" encoding="utf-8" ?>
<cities>
    <city>Washington DC</city>    
    <city>Islamabad</city>
    <city>Beijing</city>
    <city>Tokyo</city>
</cities>

Vou usar AJAX para ler esse arquivo XML e, em seguida, percorrê-lo com o laço do while. O código abaixo imprime todos os nomes das cidades (dados no arquivo XML) na janela do console.

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "XMLFile1.xml", true);
xhttp.send();

function myFunction(xml) {
    var xmlDoc = xml.responseXML;
    var cityNames = Array.from(xmlDoc.getElementsByTagName("city"));
    var i = 0;  
    
    do {
        console.log(cityNames[i].innerHTML);
        i++;
    }
    while (i < cityNames.length);
}

Explicação: Criei um objeto XMLHttpRequest para fazer a chamada AJAX. Quando o arquivo XML é lido, o evento chamado onreadystatechange é gerado, veja o código abaixo:

xhttp.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};

Nesse evento, estou chamando minha função personalizada chamada myFunction(). Aqui, armazeno o conteúdo XML dentro de uma variável chamada xmlDoc:

var xmlDoc = xml.responseXML;

Converti todos os nomes das cidades em um array:

var cidadeNomes = Array.from(xmlDoc.getElementsByTagName("cidade"));

Por fim, percorro esse array de cidades usando o laço do while e imprimo na janela do console o nome de cada cidade:

var i = 0;
do {
    console.log(cidadeNomes[i].innerHTML);
    i++;
}
while (i < cidadeNomes.length);

A imagem abaixo mostre a saída impressa no console:

1_tzh2L8Ywe2ELU9GtmFznEA
Valores do array cidadesNomes do XML

5. O método ".forEach()"

A versão ES6 tem um método chamado .forEach() para percorrer um array de elementos. Você o achará muito útil ao lidar com arrays.

a. Percorrendo um array com o método .forEach():

Nessa situação, percorro os elementos de um array com o método .forEach() e imprimo o índice e o valor de cada elemento na janela do console. Veja o código abaixo:

var nomes = ["jerry", "tom", "pluto", "micky", "mini"];
nomes.forEach(Function1);

function Function1(currentValue, index) {
    console.log("Indice atual do array é: " + index + " :: Valor é: " + currentValue);
}

Function1 é o nome da função que é chamada para cada elemento do array. No meu caso, a função será chamada 5 vezes. Ela aceita 2 parâmetros — 'index' e 'value' do elemento atual.

Note que você pode converter um objeto em um array usando o método Array.from().

var linksArr = Array.from(links);

Conclusão

Obrigado pela leitura deste tutorial. Espero que tenha ensinado algo novo sobre como lidar com laços em JavaScript. Agora, você pode aplicar qualquer uma de suas táticas de uso dos laços favoritas, descritas neste tutorial, em seu projeto da web.

Publiquei outro tutorial no freeCodeCamp, caso você queira vê-lo também: How to create a login feature with Bootstrap Modal and jQuery AJAX

Mais uma vez, obrigado e bons estudos!