Iagovar

Javascript: ¿Qué diferencias hay entre los bucles for of y for in?

La diferencia puede resultar confusa para quienes vienen de Python. Lo aclaramos.

Si alguien llega a JavaScript desde la simplicidad de Python le puede costar diferenciar los bucles for in de los for of.

for (valor [in/of] colección) {}
valor devuelve:
Bucle Itera sobre Sobre Array Sobre Objeto
for in Propiedades de un objeto Un índice Una clave
for of Valores de un iterable, como son: Arrays, Strings, Maps, NodeLists, etc. Pero NO objetos. Un valor Error, no es iterable


// ==== Definamos un Array y un objeto para probar después ====

const array = ["hola", 1,2,3, true, null, "adios"]
array.propiedadPersonalizada = "Esto es una propiedad personalziada";

console.log(array)
// ["hola", 1, 2, 3, true, null, "adios"] -> Observa que no incluye la propiedad

const objeto = {primera_clave: "primer_valor", segunda_clave: "segundo_valor"}

Probemos con for in:


// ==== Hagamos pruebas con los bucles ====

// Problemos FOR IN
for (elemento in array) {
    console.log(`Esto muestra es un indice: ${elemento} y esto un valor: ${array[elemento]}`)
}

/*
    "Esto muestra es un indice: 0 y esto un valor: hola"
    "Esto muestra es un indice: 1 y esto un valor: 1"
    "Esto muestra es un indice: 2 y esto un valor: 2"
    "Esto muestra es un indice: 3 y esto un valor: 3"
    "Esto muestra es un indice: 4 y esto un valor: true"
    "Esto muestra es un indice: 5 y esto un valor: null"
    "Esto muestra es un indice: 6 y esto un valor: adios"
    "Esto muestra es un indice: propiedadPersonalizada y esto un valor: Esto es una propiedad personalziada"
*/

for (elemento in objeto) {
    console.log(`Esto muestra la clave: ${elemento} y esto el valor: ${objeto[elemento]}`)
}

/*
    "Esto muestra la clave: primera_clave y esto el valor: primer_valor"
    "Esto muestra la clave: segunda_clave y esto el valor: segundo_valor"
*/


Probemos con for of:


for (elemento of array) {
  console.log(elemento)
}

/*
  "hola"
  1
  2
  3
  true
  null
  "adios"
*/

for (elemento of objeto) {
  console.log(elemento)
}

// TypeError: objeto is not iterable

El cuadro superior resume bien la situación, pero ver el código puede ser útil.