Movatterモバイル変換


[0]ホーム

URL:


  1. Tecnología web para desarrolladores
  2. JavaScript
  3. Referencia de JavaScript
  4. Protocolos de Iteración

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

Protocolos de Iteración

Las nuevas características de ECMAScript 6 no solo están asociadas a cambios y adiciones de sintaxis o a nuevos objetos nativos, sino también a protocolos. Dichos protocolos puede ser implementados por cualquier objeto en relación a algunas convenciones.Existen dos protocolos: Elprotocolo iterable y elprotocolo iterador.

El protocolo iterable

El protocoloiterable le permite a los objetos en JavaScript definir o personalizar su comportamiento de iteración, como por ejemplo qué valores son iterados dentro de una sentenciafor..of. Algunos objetos nativos, comoArray oMap, tienen un comportamiento de iteración por defecto, mientras otros objetos (como por ejemploObject) no.

Para ser iterable, un objeto debe implementar el método@@iterator, lo cual significa que el objeto (o uno de los objetos dentro de sucadena de prototipos) debe tener una propiedad con un identificadorSymbol.iterator:

Propiedad

[Symbol.iterator]

Valor

Una función sin argumentos que retorna un objeto, de acuerdo alprotocolo iterador.

Siempre que un objeto necesite ser iterado (como al comienzo de unfor..of loop), su método@@iterator es llamado sin argumentos, y eliterador retornado es usado para obtener los valores a ser iterados.

El protocolo iterador

El protocoloiterador define una forma estándar que permite producir una secuencia de valores (sean estos finitos o infinitos).

Un objeto es un iterador cuando este implementa un métodonext() con la siguiente semántica:

Propiedad

next

Valor

Una función sin argumentos que retorna un objeto con dos propiedades:

  • done (boleano)

    • Su valor estrue si el iterador está más allá del final de la secuencia iterada. En este casovalue opcionalmente especifica elvalor retornado por el iterador. Los valores retornados son explicadosaquí.
    • Su valor esfalse si el iterador pudo producir el siguiente valor en la secuencia. Esto es equivalente a no especificar la propiedaddone en su totalidad.
  • value - cualquier valor de JavaScript retornado por el iterador. Puede ser omitido cuando el valor dedone estrue.

Algunos iteradores son a su vez iterables:

js
var someArray = [1, 5, 7];var someArrayEntries = someArray.entries();someArrayEntries.toString(); // "[object Array Iterator]"someArrayEntries === someArrayEntries[Symbol.iterator](); // true

Ejemplos de protocolos de iteración

UnString es un ejemplo de un objeto iterable nativo:

js
var someString = "hi";typeof someString[Symbol.iterator]; // "function"

Para objetosString su iterador por defecto retorna cada uno de sus caracteres, uno a la vez:

js
var iterator = someString[Symbol.iterator]();iterator + ""; // "[object String Iterator]"iterator.next(); // { value: "h", done: false }iterator.next(); // { value: "i", done: false }iterator.next(); // { value: undefined, done: true }

En algunas estructuras nativas del lenguaje como en el caso deloperador de propagaciónspread operator, el mismo protocolo de iteración está presente en su parte interna:

js
[...someString]; // ["h", "i"]

Podemos redefinir el comportamiento de iteración creando nuestro propio@@iterator:

js
// es necesario el uso de un objeto creado a partir de la función constructora String,// ya que al usar un string primitivo el auto-boxing generaría una referencia temporal// a un iterador que luego es descartado en el unboxvar someString = new String("hi");someString[Symbol.iterator] = function () {  return {    // este es el objeto iterador que retorna un único elemento, la cadena string "bye"    next: function () {      if (this._first) {        this._first = false;        return { value: "bye", done: false };      } else {        return { done: true };      }    },    _first: true,  };};

Nótese que al redefinir un@@iterator se puede afectar el comportamiento de construcciones nativas que usan el protocolo de iteración:

js
[...someString]; // ["bye"]someString + ""; // "hi"

Ejemplos de iterables

Iterables nativos

String,Array,TypedArray,Map ySet son objetos iterables nativos, ya que en su objeto prototipo existe un método@@iterator.

Iterables personalizados

Podemos crear nuestros propios iterables de la siguiente manera:

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

APIs nativas que aceptan iterables

Existen varios APIs que aceptan iterables, como en el caso de:Map([iterable]),WeakMap([iterable]),Set([iterable]) yWeakSet([iterable]):

js
var myObj = {};new Map([  [1, "a"],  [2, "b"],  [3, "c"],]).get(2); // "b"new WeakMap([  [{}, "a"],  [myObj, "b"],  [{}, "c"],]).get(myObj); // "b"new Set([1, 2, 3]).has(3); // truenew Set("123").has("2"); // truenew WeakSet(  (function* () {    yield {};    yield myObj;    yield {};  })(),).has(myObj); // true

De igual maneraPromise.all(iterable),Promise.race(iterable), yArray.from().

Sintaxis que espera un iterable

Algunas declaraciones y expresiones esperan iterables, por ejemplo el buclefor-of, eloperador de propagaciónspread operator, la expresiónYield*, y laasignación desestructuradadestructuring assignment.

js
for (let value of ["a", "b", "c"]) {  console.log(value);}// "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"

Iterables mal definidos

Un método@@iterator iterable que no retorne un objeto iterador no está correctamente definido, por lo tanto al ejecutarlo de esta manera podría resultar en excepciones en tiempo de ejecución y otros errores:

js
var nonWellFormedIterable = {}nonWellFormedIterable[Symbol.iterator] = () => 1[...nonWellFormedIterable] // TypeError: [] is not a function

Ejemplos de iteradores

Iterador simple

js
function makeIterator(array) {  var nextIndex = 0;  return {    next: function () {      return nextIndex < array.length        ? { value: array[nextIndex++], done: false }        : { done: true };    },  };}var it = makeIterator(["yo", "ya"]);console.log(it.next().value); // 'yo'console.log(it.next().value); // 'ya'console.log(it.next().done); // true

Iterador infinito

js
function idMaker() {  var index = 0;  return {    next: function () {      return { value: index++, done: false };    },  };}var it = idMaker();console.log(it.next().value); // '0'console.log(it.next().value); // '1'console.log(it.next().value); // '2'// ...

Con un generador

js
function* makeSimpleGenerator(array) {  var nextIndex = 0;  while (nextIndex < array.length) {    yield array[nextIndex++];  }}var gen = makeSimpleGenerator(["yo", "ya"]);console.log(gen.next().value); // 'yo'console.log(gen.next().value); // 'ya'console.log(gen.next().done); // truefunction* idMaker() {  var index = 0;  while (true) yield index++;}var gen = idMaker();console.log(gen.next().value); // '0'console.log(gen.next().value); // '1'console.log(gen.next().value); // '2'// ...

¿Un objeto generador es un iterador o un iterable?

Unobjeto iterador es tanto un iterador como un iterable:

js
var aGeneratorObject = (function* () {  yield 1;  yield 2;  yield 3;})();typeof aGeneratorObject.next;// "function", ya que tiene un método next, por lo tanto es un iteradortypeof aGeneratorObject[Symbol.iterator];// "function", ya que tiene un método @@iterator, por lo tanto es un iterableaGeneratorObject[Symbol.iterator]() === aGeneratorObject;// true, ya que su método @@iterator retorna a sí mismo (un iterador), por lo tanto es un iterable bien formado[...aGeneratorObject];// [1, 2, 3]

Especificaciones

Specification
ECMAScript® 2026 Language Specification
# sec-iteration

Temas relacionados

Para información adicional acerca de generadoresgenerators en ES6, puede visitar lapágina específica sobre este tema.

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp