Qual a diferença entre for, forEach e
for...of?
Existem inúmeras maneiras de fazer laços em arrays e objetos no Javascript. Vamos ver algumas diferenças entre elas:
Diferenças de sintaxe
O que acontece com as construções for e for... in?
Esses loops fornecem acesso apenas ao índice do array, e não ao elemento em si. Vejamos os exemlos:
function loopComFor() {
let numeros = [10, 20, 30, 40, 50]
for (let i = 0; i < numeros.length; i++) {
console.log(i) // 0, 1, 2, 3, 4
}
}
function loopComForIn() {
let numeros = [10, 20, 30, 40, 50]
for (const numero in numeros) {
console.log(numero) // 0, 1, 2, 3, 4
}
}
Apesar de ter dado o nome "numero", um nome mais adequado seria "índice", já que o valor retornado não é o elemento.
O que acontece com as construções forEach e for... of?
Ao contrário das outras, essas te dão acesso ao próprio elemento do array. Com o forEach é até mesmo possível acessar também o índice, pasando um segundo parâmetro.
function loopComForIn() {
let numeros = [10, 20, 30, 40, 50]
for (const numero of numeros) {
console.log(numero) // 10, 20, 30, 40, 50
}
}
function loopComForEach() {
let numeros = [10, 20, 30, 40, 50]
numeros.forEach((numero, indice) => {
console.log("Numero " + numero + " na posição " + indice)
})
}
Porém, o que acontece caso o Array tenha uma chave não-numérica?
Considere o exemplo:
const arr = ['a', 'b', 'c'];
arr.test = 'bad';
Esse código retorna um array com a seguinte estrutura:
['a', 'b', 'c', test: 'bad'] //arr.length continua sendo 3
Nesse caso, o loop for... in é o único dos 4 que não ignora
corretamente a chave não-numérica e, por isso, geralmente deve ser evitado ao percorrer um Array.
E se o elemento tiver espaços vazios?
Considerando o array com espaço vazio:
const arrayComVazio = ['a',, 'c'];
arrayComVazio.length; // 3
Vamos a mais um exemplo:
// Mostra "a, undefined, c"
for (let i = 0; i < arrayComVazio.length; ++i) {
console.log(arr[i]);
}
// Mostra "a, c"
arrayComVazio.forEach(v => console.log(v));
// Mostra "a, c"
for (let i in arrayComVazio) {
console.log(arrayComVazio[i]);
}
// Mostra "a, undefined, c"
for (const v of arrayComVazio) {
console.log(v);
}
Dos 4, apenas o forEach e o for...in pulam o elemento vazio.
PS: Apesar de, por conta dos problemas listados dos outros loops, o o loop forEach parecer ser "o melhor", lembre-se que cada um possui sua aplicação. O loop forEach, por exemplo, não se dá muito bem com funções assíncronas.