Movatterモバイル変換


[0]ホーム

URL:


  1. Tecnología web para desarrolladores
  2. JavaScript
  3. Guía de JavaScript
  4. Iteradores y generadores

Esta página ha sido traducida del inglés por la comunidad.Aprende más y únete a la comunidad de MDN Web Docs.

View in EnglishAlways switch to English

Iteradores y generadores

Procesar cada uno de los elementos en una colección es una operación muy común. JavaScript proporciona diversas formas de iterar sobre una colección, desde simples buclesfor hasta métodos comomap() yfilter(). Los iteradores y los generadores traen el concepto de iteración al centro del lenguaje y proporcionan un mecanismo para personalizar el comportamiento de los buclesfor...of.

Para más información, véase:

Iteradores

En JavaScript, uniterador es un objeto que permite recorrer una colección y devolver un valor al terminar.

Específicamente, un iterador es un objeto que implementa elprotocolo de iteración a través del métodonext(), el cual devuelve un objeto con dos propiedades:

value

El siguiente valor en la secuencia de iteración.

done

Estrue si el último valor en la secuencia ya ha sido consumido. Sivalue está presente junto condone, es el valor de retorno del iterador.

Un iterador se considera ya terminado/finalizado cuando la invocación denext() regresa un objeto donde la propiedaddone esverdadero.

Una vez creado, un objeto iterador puede utilizarse explícitamente llamando repetidamente al métodonext().

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 métodonext() para acceder a las parejas llave-valor del objeto en cuestión:

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 creación require una programación meticulosa ya que necesitan mantener su estado interno explícitamente. Losgeneradores son una alternativa poderosa: permiten definir un algoritmo iterativo al escribir una sola función que puede mantener su propio estado.

Una función generadora (constructor GeneratorFunction) es un tipo especial de función que sirve como una fábrica de iteradores. Cuando se ejecuta, regresa un nuevo objeto Generador. Una función se convierte en una Función Generadora si utiliza la sintáxisfunction*.

js
function* hacedorIds() {  var indice = 0;  while (true) {    yield indice++;  }}var gen = hacedorIds();console.log(gen.next().value); // 0console.log(gen.next().value); // 1console.log(gen.next().value); // 2// ...

Iterables

Un objeto esiterable si define cómo se itera. Un ejemplo son los valores que se iteran en un buclefor...of. Algunos tipos integrados de datos, comoArray oMap, tienen una forma de iteración ya definida, mientras que otras no (comoObject).

Con el fin de seriterable, un objeto debe implementar el método@@iterator. Esto quiere decir que dicho objeto (o alguno en sucadena de prototipos) debe tener una propiedad definida usando la llaveSymbol.iterator. Esta función debería regresar un nuevo iterador en cada invocación, 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,Objetos_globales/TypedArray,Map ySet son iterables ya integrados, porque todos sus objetos prototipo tienen un método definido con la llaveSymbol.iterator.

Sintaxis que esperan objetos iterables

Algunas sentencias y expresiones esperan objetos iterables, por ejemplo los buclesfor-of,el operador de propagación,yield*, yla asignación por desestructuración.

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 métodonext() también acepta un valor que puede ser utilizado para modificar el estado interno del generador. El valor recibido pornext() es utilizado como si fuera el resultado de la iteración anterior (último valor entregado poryield) el cual detuvo al generador.

A continuación se muestra un generador de Fibonacci usandonext(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); // 1console.log(secuencia.next().value); // 1console.log(secuencia.next().value); // 2console.log(secuencia.next().value); // 3console.log(secuencia.next().value); // 5console.log(secuencia.next().value); // 8console.log(secuencia.next().value); // 13console.log(secuencia.next(true).value); // 1console.log(secuencia.next().value); // 1console.log(secuencia.next().value); // 2console.log(secuencia.next().value); // 3

Es posible forzar a un generador a lanzar una excepción cuando se invoca al métodothrow() y se pasa el valor de excepción a lanzar. Esta excepción será lanzada desde el contexto actual suspendido del generador, como si en vez del estado suspendido actualmente deyield se tuviera una sentenciathrow valor.

Si la excepción no es atrapada dentro del generador, se propagará a la invocación dethrow(), y las siguientes llamadas anext() tendrán a la propiedaddone enverdadero.

Los generadores tienen un métodoreturn(valor) que regresa el valor enviado y finalizan al generador.

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp