Quiz

Que construções de idioma você usa para iterar sobre propriedades de objeto e itens de matriz?

Topics
JavaScript
Edit on GitHub

Objetos

declaração for...in

for (const property in obj) {
console.log(property);
}

A declaração for...in itera sobre todas as propriedades enumeráveis do objeto (incluindo as propriedades enumeráveis herdadas). Portanto, na maioria das vezes, você deve verificar se a propriedade existe diretamente no objeto por meio de Object.hasOwn(object, property) antes de usá-la.

for (const property in obj) {
if (Object.hasOwn(obj, property)) {
console.log(property);
}
}

Observe que obj.hasOwnProperty() não é recomendado porque não funciona para objetos criados usando Object.create(null). É recomendado usar Object.hasOwn() nos navegadores mais recentes, ou use o bom Object.prototype.hasOwnProperty.call(object, key).

Object.keys()

Object.keys(obj).forEach((property) => {
console.log(property);
});

Object.keys() é um método estático que retornará um array com todos os nomes de propriedade enumerados do objeto que você passa. Uma vez que Object.keys() retorna um array, você também pode usar as abordagens de iteração de matriz listadas abaixo para iterar através dele.

Referência: Object.keys() - JavaScript | MDN

Object.getOwnPropertyNames()

Object.getOwnPropertyNames(obj).forEach((property) => {
console.log(property);
});

Object.getOwnPropertyNames() é um método estático que listará todas as propriedades enumeradas e não-enumeráveis do objeto que você passou. Uma vez que Object.getOwnPropertyNames() retorna uma matriz, você também pode usar as abordagens de iteração de matriz listadas abaixo para percorrer a matriz.

Referência: Object.keys() - JavaScript | MDN

Arrays

for loop

for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}

Uma armadilha comum aqui é que var está no escopo da função e não no escopo de bloco, e na maioria das vezes você desejará uma variável de iterador com escopo de bloco. ES2015 introduz o let que tem escopo de bloco e é recomendado usar let em vez de var.

for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}

Array.prototype.forEach()

arr.forEach((element, index) => {
console.log(element, index);
});

O método Array.prototype.forEach() pode ser mais conveniente em algumas situações se você não precisar usar o índice e só precisar dos elementos individuais do array. No entanto, o lado negativo é que não se pode parar a iteração a meio do caminho e a função fornecida será executada uma vez nos elementos. Um laço for ou uma declaração for...of são mais relevantes quando é necessário um controle mais preciso sobre a iteração.

Referência: Object.keys() - JavaScript | MDN

declaração for...of

for (let element of arr) {
console.log(element);
}

ES2015 introduz uma nova forma de iterar, o laço para, que permite repetir o loop sobre objetos que estejam em conformidade com o protocolo iterável como String, Array, Set, etc. Ele combina as vantagens do loop for e do método forEach(). A vantagem do laço para é que você pode parar dele, e a vantagem de forEach() é que ele é mais conciso que o laço for porque você não precisa de uma variável contadora. Com a declaração for...of, você obtém a capacidade de quebrar de um laço e uma sintaxe mais concisa.

A maioria das vezes, prefira o método .forEach, mas realmente depende do que você está tentando fazer. Antes do ES2015, usamos laços for quando precisávamos encerrar prematuramente o laço usando break. Mas agora com ES2015, podemos fazer isso com a declaração for...of. Use laços for quando você precisar de mais flexibilidade, como incrementar o iterador mais de uma vez por laço.

Além disso, ao usar o for...of declaração, se você precisar acessar o índice e o valor de cada elemento de matriz, você pode fazer isso com ES2015 Array.prototype.entries():

const arr = ['a', 'b', 'c'];
for (let [index, elem] of arr.entries()) {
console.log(index, ': ', elem);
}

Referência: for...of - JavaScript | MDN

Edit on GitHub