Skip to content

Lección 24: for...of y for...in

JavaScript tiene dos variantes del bucle for diseñadas para casos específicos: for...of para iterables (arrays, strings, etc.) y for...in para propiedades de objetos. Son más expresivos y menos propensos a errores que el for clásico.

for...of recorre los valores de un objeto iterable (arrays, strings, Map, Set, etc.). Es la forma más limpia de recorrer un array.

let frutas = ['manzana', 'pera', 'uva'];
for (let fruta of frutas) {
console.log(fruta);
}
// manzana
// pera
// uva

Con strings:

let palabra = 'Hola';
for (let letra of palabra) {
console.log(letra);
}
// H, o, l, a

Con arrays, también puedes obtener el índice si lo necesitas:

let colores = ['rojo', 'verde', 'azul'];
for (let [indice, color] of colores.entries()) {
console.log(`${indice}: ${color}`);
}
// 0: rojo, 1: verde, 2: azul

for...in recorre las propiedades (claves) de un objeto. NO está diseñado para arrays, aunque técnicamente funcione.

let persona = {
nombre: 'Ana',
edad: 25,
ciudad: 'Madrid'
};
for (let clave in persona) {
console.log(`${clave}: ${persona[clave]}`);
}
// nombre: Ana
// edad: 25
// ciudad: Madrid
let numeros = [10, 20, 30];
for (let i in numeros) {
console.log(i); // "0", "1", "2" (strings, no números)
}

Además, for...in también recorre propiedades heredadas y métodos añadidos al prototipo del Array, lo que puede causar comportamientos inesperados.

// for...of con diferentes iterables
console.log('=== for...of con array ===');
let numeros = [1, 2, 3, 4, 5];
for (let num of numeros) {
console.log(num * 2);
}
console.log('\n=== for...of con string ===');
let saludo = 'Hola';
for (let letra of saludo) {
console.log(letra);
}
console.log('\n=== for...of con entries() ===');
let frutas = ['🍎', '🍌', '🍇'];
for (let [i, fruta] of frutas.entries()) {
console.log(`${i + 1}: ${fruta}`);
}
// for...in con objetos
console.log('\n=== for...in con objeto ===');
let producto = {
nombre: 'Laptop',
precio: 25000,
stock: 10,
disponible: true
};
for (let propiedad in producto) {
console.log(`${propiedad}: ${producto[propiedad]}`);
}
// Comparación: for...of vs forEach
console.log('\n=== Comparación ===');
let datos = ['a', 'b', 'c'];
// for...of (puedes usar break/continue)
for (let d of datos) {
if (d === 'b') continue;
console.log(d);
}
// a, c
// forEach (no puedes usar break/continue)
datos.forEach(function(d) {
console.log(d);
});
// a, b, c
  1. Crea un archivo for-of-for-in.js.
  2. Declara un array ciudades con 5 nombres de ciudades.
  3. Usa for...of para imprimir cada ciudad en mayúsculas.
  4. Declara un objeto libro con titulo, autor, año, genero.
  5. Usa for...in para imprimir cada propiedad y su valor.
  6. Usa for...of con .entries() para imprimir índice + ciudad.
  7. Usa for...of con un string para contar vocales.
let ciudades = ['CDMX', 'Bogotá', 'Lima', 'Santiago', 'Buenos Aires'];
console.log('=== Ciudades ===');
for (let ciudad of ciudades) {
console.log(ciudad.toUpperCase());
}
let libro = {
titulo: 'Cien Años de Soledad',
autor: 'Gabriel García Márquez',
año: 1967,
genero: 'Realismo mágico'
};
console.log('\n=== Libro ===');
for (let prop in libro) {
console.log(`${prop}: ${libro[prop]}`);
}
console.log('\n=== Ciudades con índice ===');
for (let [i, ciudad] of ciudades.entries()) {
console.log(`${i + 1}. ${ciudad}`);
}
// Contar vocales
let texto = 'JavaScript es increíble';
let vocales = 0;
for (let letra of texto) {
if ('aeiouáéíóúAEIOU'.includes(letra)) {
vocales++;
}
}
console.log(`\nVocales en "${texto}": ${vocales}`);

Nunca uses for...in para recorrer arrays. Usa for...of, .forEach(), o el for clásico. for...in está diseñado para objetos con propiedades enumerables, no para colecciones ordenadas como los arrays.

// ❌ Mal: for...in en array
let arr = [10, 20, 30];
for (let i in arr) {
console.log(arr[i]); // funciona, pero es incorrecto
}
// ✅ Bien: for...of en array
for (let val of arr) {
console.log(val);
}

for...of también funciona con otros iterables como Map, Set, NodeList (en el navegador) y hasta generadores. Es el bucle más versátil de JavaScript moderno.

let mapa = new Map([['a', 1], ['b', 2]]);
for (let [clave, valor] of mapa) {
console.log(clave, valor);
}