Entonces, vamos a tratar de descubrir más sobre lo que realmente significa ser iterable. Pero para hacer eso, creo que es muy útil aprender un poco más sobre los generadores, que creo que es un concepto que aún no es muy conocido en el panorama de JavaScript.
Si nunca has visto generadores, existe este concepto de funciones generadoras y objetos generadores. Una función generadora se ve como una función, pero es un poco especial. Tienes que poner un asterisco allí. Y lo que ganamos si ponemos ese asterisco es que ahora podemos usar esta palabra clave llamada yield.
Y lo que yield hace es una especie de retorno especial. Te permite devolver un valor, pero en lugar de detener la ejecución de la función en particular, va a recordar exactamente dónde nos detuvimos la última vez. Así que es más como una pausa que detener realmente la ejecución de la función. Y podemos reanudar esa ejecución desde el punto donde se dejó en la iteración anterior.
Pero ¿cómo usamos una función generadora? Bueno, podemos invocarla como una función regular, y eso nos va a devolver un objeto generador. Y en un objeto generador, podemos seguir llamando a dot next dot next, y cada vez recibiremos un objeto que contiene las claves done y value que básicamente nos dicen si hay más datos, sí o no, y este es el valor actual.
Ahora permíteme mostrarte un ejemplo más interesante donde, lo siento, tenemos varios puntos de yield. Este es un generador de frutas, así que cada instancia estamos devolviendo una nueva fruta, o estamos haciendo yield de una nueva fruta. Y cuando llamamos a dot next dot next, puedes ver que obtenemos cada vez un elemento diferente, por lo que puedes imaginar que la ejecución se pausa cuando hacemos yield. Y cuando llamamos a dot next de nuevo, va a continuar desde la línea donde pausamos la última vez.
Lo interesante es que también podemos usar for of, y si usamos for of en objetos generadores, obtenemos acceso directo a los valores. Ya no tenemos que pensar en ese objeto envolvente, y el bucle se detendrá automáticamente cuando lleguemos a done igual a true.
Ahora finalmente podemos hablar de los iteradores y los iterables. Estos son dos conceptos diferentes, muy similares, que a menudo se confunden, así que intentemos entender cuáles son las diferencias entre los dos. Me gusta pensar en los objetos iteradores como un cursor en una colección de datos. Así que puedes imaginar que esa flecha amarilla es un objeto iterador. Lo único que podemos hacer con él es decir, dame el valor actual o muévete al siguiente valor.
Mientras que un objeto iterable es un concepto ligeramente más genérico, es más la idea de que tienes una colección y esta colección es de alguna manera iterable, y la forma en que puedes iterar sobre ella es obtener un iterador de esa colección. Así que nuevamente, puedes imaginar el iterador como el cursor, el iterable como la idea de una colección de la que puedes obtener un cursor.
Ahora, si queremos entender qué considera JavaScript como iterable e iterador, necesitamos mirar esos protocolos de iteración, y el primer protocolo es el protocolo del iterador, que nos dice, voy a considerar un objeto si cumple con esta definición, y la definición dice que el objeto debe tener un método llamado next, y este método, cada vez que lo llames, debe devolver un objeto con las claves done y value.
Ahora, solo para mostrarte un ejemplo muy rápido, aquí tenemos una función de fábrica que nos permite crear un iterador que representa una cuenta regresiva, así que si llamamos a esta función, por ejemplo, con 3, va a crear un iterador que nos dará los valores 3, 2, 1, 0, ¿verdad? Así que queremos implementar este iterador, así que necesitamos cumplir con la definición del protocolo de iteración. Así que necesitamos tener un objeto que tenga un método next, que devuelva objetos con las claves done y value. Así que básicamente esta es una función de fábrica que crea un iterador para nosotros. Y una vez que lo hacemos, podemos instanciarlo, count down es un iterador.
Comments