[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Iterators_and_generators#Iterables [Back]  [Original]

Iteradores y generadores - JavaScript | MDN

Esta pgina ha sido traducida del ingls por la comunidad. Aprende ms y nete a la comunidad de MDN Web Docs.

View in English Always switch to English

Iteradores y generadores

Procesar cada uno de los elementos en una coleccin es una operacin muy comn. JavaScript proporciona diversas formas de iterar sobre una coleccin, desde simples bucles for hasta mtodos como map() y filter(). Los iteradores y los generadores traen el concepto de iteracin al centro del lenguaje y proporcionan un mecanismo para personalizar el comportamiento de los bucles for...of.

Para ms informacin, vase:

In this article

Iteradores

En JavaScript, un iterador es un objeto que permite recorrer una coleccin y devolver un valor al terminar.

Especficamente, un iterador es un objeto que implementa el protocolo de iteracin a travs del mtodo next(), el cual devuelve un objeto con dos propiedades:

value

El siguiente valor en la secuencia de iteracin.

done

Es true si el ltimo valor en la secuencia ya ha sido consumido. Si value est presente junto con done, es el valor de retorno del iterador.

Un iterador se considera ya terminado/finalizado cuando la invocacin de next() regresa un objeto donde la propiedad done es verdadero.

Una vez creado, un objeto iterador puede utilizarse explcitamente llamando repetidamente al mtodo next().

js
function crearIterador(arreglo) {
  var siguienteIndice = 0;

  return {
    next: function () {
      return siguienteIndice < arreglo.length
        ? { value: arreglo[siguienteIndice++], done: false }
        : { done: true };
    },
  };
}

Una vez inicializado, se puede invocar al mtodo next() para acceder a las parejas llave-valor del objeto en cuestin:

js
var it = crearIterador(["yo", "ya"]);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true

Generadores

Aunque los iteradores personalizados son una herramienta til, su creacin require una programacin meticulosa ya que necesitan mantener su estado interno explcitamente. Los generadores son una alternativa poderosa: permiten definir un algoritmo iterativo al escribir una sola funcin que puede mantener su propio estado.

Una funcin generadora (constructor GeneratorFunction) es un tipo especial de funcin que sirve como una fbrica de iteradores. Cuando se ejecuta, regresa un nuevo objeto Generador. Una funcin se convierte en una Funcin Generadora si utiliza la sintxis function*.

js
function* hacedorIds() {
  var indice = 0;
  while (true) {
    yield indice++;
  }
}

var gen = hacedorIds();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// ...

Iterables

Un objeto es iterable si define cmo se itera. Un ejemplo son los valores que se iteran en un bucle for...of. Algunos tipos integrados de datos, como Array o Map, tienen una forma de iteracin ya definida, mientras que otras no (como Object).

Con el fin de ser iterable, un objeto debe implementar el mtodo @@iterator. Esto quiere decir que dicho objeto (o alguno en su cadena de prototipos) debe tener una propiedad definida usando la llave Symbol.iterator. Esta funcin debera regresar un nuevo iterador en cada invocacin, pero no es obligatorio.

Iterables definidos por el usuario

Podemos hacer nuestros propios objetos iterables de este modo:

js
var miIterable = {};
miIterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

for (let valor of miIterable) {
  console.log(valor);
}
// 1
// 2
// 3

// 

[...miIterable]; // [1, 2, 3]

Iterables integrados

String, Array, TypedArray, Map y Set son iterables ya integrados, porque todos sus objetos prototipo tienen un mtodo definido con la llave Symbol.iterator.

Sintaxis que esperan objetos iterables

Algunas sentencias y expresiones esperan objetos iterables, por ejemplo los bucles for-of, el operador de propagacin, yield*, y la asignacin por desestructuracin.

js
for (let valor of ["a", "b", "c"]) {
  console.log(valor);
}
// "a"
// "b"
// "c"

[..."abc"]; // ["a", "b", "c"]

function* gen() {
  yield* ["a", "b", "c"];
}

gen().next(); // { value:"a", done:false }

[a, b, c] = new Set(["a", "b", "c"]);
a; // "a"

Generadores avanzados

Los generadores calculan los valores devueltos bajo demanda, lo que les permite representar eficientemente secuencias que son costosas de calcular, o incluso secuencias infinitas como se explic anteriormente.

El mtodo next() tambin acepta un valor que puede ser utilizado para modificar el estado interno del generador. El valor recibido por next() es utilizado como si fuera el resultado de la iteracin anterior (ltimo valor entregado por yield) el cual detuvo al generador.

A continuacin se muestra un generador de Fibonacci usando next(x) para reiniciar la secuencia:

js
function* fibonacci() {
  var fn1 = 1;
  var fn2 = 1;
  while (true) {
    var actual = fn2;
    fn2 = fn1;
    fn1 = fn1 + actual;
    var reset = yield actual;
    if (reset) {
      fn1 = 1;
      fn2 = 1;
    }
  }
}

var secuencia = fibonacci();
console.log(secuencia.next().value); // 1
console.log(secuencia.next().value); // 1
console.log(secuencia.next().value); // 2
console.log(secuencia.next().value); // 3
console.log(secuencia.next().value); // 5
console.log(secuencia.next().value); // 8
console.log(secuencia.next().value); // 13
console.log(secuencia.next(true).value); // 1
console.log(secuencia.next().value); // 1
console.log(secuencia.next().value); // 2
console.log(secuencia.next().value); // 3

Es posible forzar a un generador a lanzar una excepcin cuando se invoca al mtodo throw() y se pasa el valor de excepcin a lanzar. Esta excepcin ser lanzada desde el contexto actual suspendido del generador, como si en vez del estado suspendido actualmente de yield se tuviera una sentencia throw valor.

Si la excepcin no es atrapada dentro del generador, se propagar a la invocacin de throw(), y las siguientes llamadas a next() tendrn a la propiedad done en verdadero.

Los generadores tienen un mtodo return(valor) que regresa el valor enviado y finalizan al generador.


Web Proxy Viewer  |  New URL  |  Original Page