[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Iteration_protocols [Back]  [Original]

Les protocoles d'itration - JavaScript | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

Les protocoles d'itration

Les protocoles d'itration ne sont pas de nouvelles constructions ou syntaxes du langage, mais des protocoles. Ces protocoles peuvent tre implments par n'importe quel objet en respectant certaines conventions.

Il existe deux protocoles concernant l'itration : le protocole  itrable  et le protocole  itrateur .

Dans cet article

Le protocole itrable

Le protocole itrable permet aux objets JavaScript de dfinir ou de personnaliser leur comportement d'itration, par exemple les valeurs parcourues dans une construction for...of. Certains types natifs sont des itrables natifs avec un comportement d'itration par dfaut, comme Array ou Map, tandis que d'autres types (comme Object) ne le sont pas.

Pour qu'un objet soit itrable, il doit implmenter la mthode [Symbol.iterator](), c'est--dire que l'objet (ou l'un des objets de sa chane de prototypes) doit possder une proprit dont la cl est [Symbol.iterator], accessible via la constante Symbol.iterator :

[Symbol.iterator]()

Une fonction sans argument qui retourne un objet conforme au protocole  itrateur .

Chaque fois qu'un objet doit tre parcouru (par exemple au dbut d'une boucle for...of), sa mthode [Symbol.iterator]() est appele sans argument, et l'itrateur retourn est utilis pour obtenir les valeurs parcourir.

Notez que lorsque cette fonction sans argument est appele, elle l'est en tant que mthode sur l'objet itrable. Ainsi, l'intrieur de la fonction, le mot-cl this permet d'accder aux proprits de l'objet itrable afin de dcider quoi fournir lors de l'itration.

Cette fonction peut tre une fonction ordinaire ou une fonction gnratrice, de sorte qu'un objet itrateur est retourn lorsqu'elle est invoque. l'intrieur de cette fonction gnratrice, chaque entre peut tre fournie l'aide de yield.

Le protocole itrateur

Le protocole itrateur dfinit une faon standard de produire une suite de valeurs (finie ou infinie), et ventuellement une valeur de retour lorsque toutes les valeurs ont t gnres.

Un objet est un itrateur lorsqu'il implmente une mthode next() avec la smantique suivante :

next()

Une fonction qui accepte zro ou un argument et qui retourne un objet conforme l'interface IteratorResult (voir cidessous). Si une valeur non objet est retourne (par exemple false ou undefined) alors qu'une fonctionnalit native du langage (comme for...of) utilise l'itrateur, une TypeError ("iterator.next() returned a non-object value") sera leve.

Toutes les mthodes du protocole itrateur (next(), return() et throw()) doivent retourner un objet implmentant l'interface IteratorResult. Cet objet doit possder les proprits suivantes :

done Facultatif

Un boolen qui vaut false si l'itrateur a pu produire la valeur suivante de la suite. (Ceci quivaut ne pas prciser la proprit done du tout.)

A la valeur true si l'itrateur a termin sa squence. Dans ce cas, value prcise ventuellement la valeur de retour de l'itrateur.

value Facultatif

Toute valeur JavaScript retourne par l'itrateur. Peut tre omise lorsque done vaut true.

En pratique, aucune des deux proprits n'est strictement requise ; si un objet sans ces proprits est retourn, cela quivaut effectivement { done: false, value: undefined }.

Si un itrateur retourne un rsultat avec done: true, tout appel ultrieur next() doit aussi retourner done: true, mme si cela n'est pas impos au niveau du langage.

La mthode next peut recevoir une valeur qui sera mise disposition dans le corps de la mthode. Aucune fonctionnalit native du langage ne transmettra de valeur. La valeur passe la mthode next des gnrateurs deviendra la valeur de l'expression yield correspondante.

Optionnellement, l'itrateur peut aussi implmenter les mthodes return(value) et throw(exception), qui, lorsqu'elles sont appeles, indiquent l'itrateur que l'appelant a fini de l'itrer et permettent d'effectuer tout nettoyage ncessaire (par exemple fermer une connexion une base de donnes).

return(value) Facultatif

Une fonction qui accepte zro ou un argument et qui retourne un objet conforme l'interface IteratorResult, gnralement avec value gal la valeur passe et done gal true. Appeler cette mthode indique l'itrateur que l'appelant n'entend pas appeler next() davantage et permet d'effectuer des actions de nettoyage. Lorsque des fonctionnalits natives appellent return() pour le nettoyage, value vaut toujours undefined.

throw(exception) Facultatif

Une fonction qui accepte zro ou un argument et qui retourne un objet conforme l'interface IteratorResult, gnralement avec done gal true. Appeler cette mthode indique l'itrateur que l'appelant signale une condition d'erreur, et exception est typiquement une instance d'Error. Aucune fonctionnalit native n'appelle throw() pour le nettoyage ; c'est une particularit des gnrateurs pour la symtrie return/throw.

Note : Il est impossible de savoir par introspection (c.--d. sans appeler rellement next() et vrifier l'objet retourn) si un objet implmente le protocole itrateur.

Il est trs facile de rendre un itrateur galement itrable : il suffit d'implmenter une mthode [Symbol.iterator]() qui retourne this.

js
// Satisfait  la fois le Protocole Iterator et Iterable
const monIterateur = {
  next() {
    // 
  },
  [Symbol.iterator]() {
    return this;
  },
};

Un tel objet s'appelle un iterable iterator. Ainsi, un itrateur peut tre consomm par les syntaxes qui attendent des itrables ; il est donc rarement utile d'implmenter uniquement le protocole itrateur sans implmenter aussi itrable. (En fait, presque toutes les syntaxes et API attendent des itrables, pas des itrateurs.) Le generator object en est un exemple :

js
const generatorObject = (function* () {
  yield 1;
  yield 2;
  yield 3;
})();

console.log(typeof generatorObject.next);
// "function"  il possde une mthode next (qui retourne le rsultat attendu), donc c'est un itrateur

console.log(typeof generatorObject[Symbol.iterator]);
// "function"  il possde une mthode [Symbol.iterator] (qui retourne l'itrateur appropri), donc c'est un itrable

console.log(generatorObject[Symbol.iterator]() === generatorObject);
// true  sa mthode [Symbol.iterator] retourne l'objet luimme (un itrateur), donc c'est un itrateur itrable

Tous les itrateurs natifs hritent de Iterator.prototype, qui implmente la mthode [Symbol.iterator]() en retournant this, de sorte que les itrateurs natifs sont aussi itrables.

Cependant, quand c'est possible, il est prfrable que iterable[Symbol.iterator]() retourne des itrateurs diffrents qui commencent toujours au dbut, comme le fait Set.prototype[Symbol.iterator]().

Les protocoles d'itrateur asynchrone et d'itrable asynchrone

Il existe une autre paire de protocoles utilise pour l'itration asynchrone, appels itrateur asynchrone et itrable asynchrone. Ils possdent des interfaces trs similaires celles des protocoles itrable et itrateur, sauf que chaque valeur retourne par les appels aux mthodes de l'itrateur est encapsule dans une promesse.

Un objet implmente le protocole d'itrable asynchrone lorsqu'il implmente les mthodes suivantes :

[Symbol.asyncIterator]()

Une fonction sans argument qui retourne un objet conforme au protocole d'itrateur asynchrone.

Un objet implmente le protocole d'itrateur asynchrone lorsqu'il implmente les mthodes suivantes :

next()

Une fonction qui accepte zro ou un argument et qui retourne une promesse. La promesse est rsolue avec un objet conforme l'interface IteratorResult, et les proprits ont les mmes smantiques que celles de l'itrateur synchrone.

return(value) Facultatif

Une fonction qui accepte zro ou un argument et qui retourne une promesse. La promesse est rsolue avec un objet conforme l'interface IteratorResult, et les proprits ont les mmes smantiques que celles de l'itrateur synchrone.

throw(exception) Facultatif

Une fonction qui accepte zro ou un argument et qui retourne une promesse. La promesse est rsolue avec un objet conforme l'interface IteratorResult, et les proprits ont les mmes smantiques que celles de l'itrateur synchrone.

Interactions entre le langage et les protocoles d'itration

Le langage dfinit des API qui produisent ou consomment des itrables et des itrateurs.

Itrables natifs

String, Array, TypedArray, Map, Set et Segments (retourn par Intl.Segmenter.prototype.segment()) sont tous des itrables natifs, car chacun de leurs objets prototype implmente une mthode [Symbol.iterator](). De plus, l'objet arguments et certains types de collections DOM comme NodeList sont aussi des itrables. Il n'existe aucun objet dans le langage JavaScript de base qui soit un itrable asynchrone. Certaines API web, comme ReadableStream, dfinissent la mthode Symbol.asyncIterator par dfaut.

Les fonctions gnratrices retournent des objets gnrateurs, qui sont des itrateurs itrables. Les fonctions gnratrices asynchrones retournent des objets gnrateurs asynchrones, qui sont des itrateurs itrables asynchrones.

Les itrateurs retourns par les itrables natifs hritent tous d'une classe commune Iterator, qui implmente la mthode [Symbol.iterator]() { return this; } mentionne plus haut, ce qui les rend tous itrateurs itrables. La classe Iterator fournit aussi des mthodes utilitaires en plus de la mthode next() requise c le protocole d'itrateur. Vous pouvez inspecter la chane de prototypes d'un itrateur en l'affichant dans une console graphique.

console.log([][Symbol.iterator]());

Array Iterator {}
  [[Prototype]]: Array Iterator     ==> Ceci est le prototype partag par tous les itrateurs de tableau
    next:  next()
    Symbol(Symbol.toStringTag): "Array Iterator"
    [[Prototype]]: Object           ==> Ceci est le prototype partag par tous les itrateurs natifs
      Symbol(Symbol.iterator):  [Symbol.iterator]()
      [[Prototype]]: Object         ==> Ceci est Object.prototype

API natives acceptant des itrables

De nombreuses API acceptent des itrables. Quelques exemples :

js
const monObjet = {};

new WeakSet(
  (function* () {
    yield {};
    yield monObjet;
    yield {};
  })(),
).has(monObjet); // true

Syntaxes attendant des itrables

Certaines instructions et expressions attendent des itrables, par exemple les boucles for...of, la syntaxe de dcomposition et l'talement des paramtres, yield*, et l'affectation par dcomposition :

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

console.log([..."abc"]); // ["a", "b", "c"]

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

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

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

Lorsque les syntaxes natives parcourent un itrateur et que le dernier rsultat de done est false (c'est--dire que l'itrateur peut encore produire des valeurs) mais qu'aucune valeur supplmentaire n'est ncessaire, la mthode return sera appele si elle existe. Cela peut arriver, par exemple, si un break ou un return est rencontr dans une boucle for...of, ou si tous les identifiants sont dj lis lors d'une dcomposition de tableau.

js
const obj = {
  [Symbol.iterator]() {
    let i = 0;
    return {
      next() {
        i++;
        console.log("Retourne", i);
        if (i === 3) return { done: true, value: i };
        return { done: false, value: i };
      },
      return() {
        console.log("Fermeture");
        return { done: true };
      },
    };
  },
};

const [a] = obj;
// Retourne 1
// Fermeture

const [b, c, d] = obj;
// Retourne 1
// Retourne 2
// Retourne 3
// Fin atteinte (le dernier appel a retourn `done: true`),
// donc `return` n'est pas appel
console.log([b, c, d]); // [1, 2, undefined] ; la valeur associe  `done: true` n'est pas accessible

for (const b of obj) {
  break;
}
// Retourne 1
// Fermeture

La boucle for await...of et yield* dans les fonctions gnratrices asynchrones (mais pas dans les fonctions gnratrices synchrones) sont les seuls moyens d'interagir avec des itrables asynchrones. Utiliser for...of, l'talement, etc. sur un itrable asynchrone qui n'est pas aussi synchrone (c'est--dire qui possde [Symbol.asyncIterator]() mais pas [Symbol.iterator]()) provoquera une TypeError : x n'est pas itrable.

Gestion des erreurs

L'itration implique un transfert de contrle entre l'itrateur et le consommateur, la gestion des erreurs se fait donc dans les deux sens : comment le consommateur gre les erreurs leves par l'itrateur, et comment l'itrateur gre les erreurs leves par le consommateur. Lorsque vous utilisez l'une des mthodes natives d'itration, le langage peut aussi lever des erreurs si l'itrable enfreint certains invariants. Nous dcrirons comment les syntaxes natives gnrent et grent les erreurs, ce qui peut servir de guide pour votre propre code si vous parcourez manuellement l'itrateur.

Itrables mal forms

Des erreurs peuvent survenir lors de l'acquisition de l'itrateur partir de l'itrable. L'invariant impos ici est que l'itrable doit produire un itrateur valide :

  • Il possde une mthode [Symbol.iterator]() appelable.
  • La mthode [Symbol.iterator]() retourne un objet.
  • L'objet retourn par [Symbol.iterator]() possde une mthode next() appelable.

Lorsque vous utilisez une syntaxe native pour initier l'itration sur un itrable mal form, une TypeError est leve.

js
const nonWellFormedIterable = { [Symbol.iterator]: 1 };
[...nonWellFormedIterable]; // TypeError : nonWellFormedIterable n'est pas itrable
nonWellFormedIterable[Symbol.iterator] = () => 1;
[...nonWellFormedIterable]; // TypeError : [Symbol.iterator]() a retourn une valeur non objet
nonWellFormedIterable[Symbol.iterator] = () => ({});
[...nonWellFormedIterable]; // TypeError : nonWellFormedIterable[Symbol.iterator]().next n'est pas une fonction

For async iterables, if its [Symbol.asyncIterator]() property has value undefined or null, JavaScript falls back to using the [Symbol.iterator] property instead (and wraps the resulting iterator into an async iterator by forwarding the methods). Otherwise, the [Symbol.asyncIterator] property must conform to the above invariants too.

Ce type d'erreurs peut tre vit en validant l'itrable avant d'essayer de l'itrer. Cependant, cela reste assez rare car, en gnral, vous connaissez le type de l'objet que vous parcourez. Si vous recevez cet itrable d'un autre code, il vaut mieux laisser l'erreur se propager l'appelant afin qu'il sache qu'une entre invalide a t fournie.

Erreurs lors de l'itration

La plupart des erreurs surviennent lors de l'avancement de l'itrateur (appel de next()). L'invariant impos ici par le langage est que la mthode next() doit retourner un objet (pour les itrateurs asynchrones, un objet aprs l'attente). Sinon, une TypeError est leve.

Si l'invariant est rompu ou si la mthode next() lve une erreur (pour les itrateurs asynchrones, elle peut aussi retourner une promesse rejete), l'erreur est propage l'appelant. Pour les syntaxes natives, l'itration en cours est interrompue sans nouvelle tentative ni nettoyage (en supposant que si la mthode next() a lev l'erreur, elle a dj effectu le nettoyage). Si vous appelez manuellement next(), vous pouvez intercepter l'erreur et ressayer d'appeler next(), mais en gnral il faut supposer que l'itrateur est dj ferm.

Si l'appelant dcide d'interrompre l'itration pour une raison autre que les erreurs du paragraphe prcdent, par exemple lorsqu'il entre dans un tat d'erreur dans son propre code (par exemple, lors du traitement d'une valeur invalide produite par l'itrateur), il doit appeler la mthode return() sur l'itrateur, si elle existe. Cela permet l'itrateur d'effectuer tout nettoyage ncessaire. La mthode return() n'est appele que pour les sorties prmaturessi next() retourne done: true, la mthode return() n'est pas appele, en supposant que l'itrateur a dj effectu le nettoyage.

La mthode return() peut aussi tre invalide ! Le langage impose galement que la mthode return() retourne un objet et lve une TypeError sinon. Si la mthode return() lve une erreur, celleci est propage l'appelant. Cependant, si la mthode return() est appele parce que l'appelant a rencontr une erreur dans son propre code, alors cette erreur prime sur l'erreur leve par la mthode return().

Habituellement, l'appelant implmente la gestion des erreurs comme ceci :

js
try {
  for (const value of iterable) {
    // 
  }
} catch (e) {
  // Grer l'erreur
}

Le catch pourra intercepter les erreurs leves lorsque iterable n'est pas un itrable valide, lorsque next() lve une erreur, lorsque return() lve une erreur (si la boucle for se termine prmaturment), et lorsque le corps de la boucle for lve une erreur.

La plupart des itrateurs sont implments avec des fonctions gnratrices, nous allons donc montrer comment les fonctions gnratrices grent typiquement les erreurs :

js
function* gen() {
  try {
    yield doSomething();
    yield doSomethingElse();
  } finally {
    cleanup();
  }
}

L'absence de catch ici fait que les erreurs leves par doSomething() ou doSomethingElse() sont propages l'appelant de gen. Si ces erreurs sont interceptes dans la fonction gnratrice (ce qui est galement conseill), la fonction gnratrice peut dcider de continuer produire des valeurs ou de se terminer prmaturment. Cependant, le bloc finally est ncessaire pour les gnrateurs qui maintiennent des ressources ouvertes. Le bloc finally est garanti de s'excuter, soit lorsque le dernier next() est appel, soit lorsque return() est appel.

Transmission des erreurs

Certaines syntaxes intgres enveloppent un itrateur dans un autre itrateur. Elles incluent l'itrateur produit par la mthode Iterator.from(), les mthodes utilitaires d'itrateur (map(), filter(), take(), drop() et flatMap()), yield*, ainsi qu'un enveloppeur cach utilis lorsque vous appliquez l'itration asynchrone (for await...of, Array.fromAsync) des itrateurs synchrones. L'itrateur envelopp est alors responsable de transfrer les erreurs entre l'itrateur interne et l'appelant.

  • Tous les itrateurs enveloppants transfrent directement la mthode next() de l'itrateur interne, y compris sa valeur de retour et les erreurs leves.
  • Les itrateurs enveloppants transfrent gnralement directement la mthode return() de l'itrateur interne. Si la mthode return() n'existe pas sur l'itrateur interne, celui-ci renvoie { done: true, value: undefined } la place. Dans le cas des assistants (helpers en anglais) d'itrateur : si la mthode next() de l'assistant n'a pas t appele, aprs avoir tent d'appeler return() sur l'itrateur interne, l'itrateur courant retourne toujours { done: true, value: undefined }. Ceci est cohrent avec les fonctions gnratrices lorsque l'excution n'est pas encore entre dans l'expression yield*.
  • yield* est la seule syntaxe intgre qui transfre la mthode throw() de l'itrateur interne. Pour des informations sur la faon dont yield* transfre les mthodes return() et throw(), voir sa propre rfrence.

Exemples

Itrables dfinis par l'utilisateurice

Vous pouvez crer vos propres itrables ainsi :

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

console.log([...myIterable]); // [1, 2, 3]

Itrateur simple

Les itrateurs sont par nature l'tat brut. Si vous ne le dfinissez pas comme une fonction gnratrice (comme le montre l'exemple cidessus), il est gnralement conseill d'encapsuler l'tat dans une fermeture.

js
function makeIterator(array) {
  let nextIndex = 0;
  return {
    next() {
      return nextIndex < array.length
        ? {
            value: array[nextIndex++],
            done: false,
          }
        : {
            done: true,
          };
    },
  };
}

const it = makeIterator(["yo", "ya"]);

console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true

Itrateur infini

js
function idMaker() {
  let index = 0;
  return {
    next() {
      return {
        value: index++,
        done: false,
      };
    },
  };
}

const it = idMaker();

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

Dfinir un itrable avec un gnrateur

js
function* makeGenerator(array) {
  let nextIndex = 0;
  while (nextIndex < array.length) {
    yield array[nextIndex++];
  }
}

const gen = makeGenerator(["yo", "ya"]);

console.log(gen.next().value); // 'yo'
console.log(gen.next().value); // 'ya'
console.log(gen.next().done); // true

function* idMaker() {
  let index = 0;
  while (true) {
    yield index++;
  }
}

const it = idMaker();

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

Dfinir un itrable avec une classe

L'encapsulation de l'tat peut galement se faire avec des champs privs (private fields).

js
class SimpleClass {
  #data;

  constructor(data) {
    this.#data = data;
  }

  [Symbol.iterator]() {
    // Utiliser un nouvel index pour chaque itrateur. Cela permet
    // d'effectuer plusieurs itrations sur l'itrable en toute scurit
    // dans des cas non triviaux, par exemple l'utilisation de break ou des
    // boucles imbriques sur le mme itrable.
    let index = 0;

    return {
      // Remarque : l'utilisation d'une fonction flche permet  this
      // de pointer vers l'objet retourn par [Symbol.iterator]() plutt que
      // vers next()
      next: () => {
        if (index >= this.#data.length) {
          return { done: true };
        }
        return { value: this.#data[index++], done: false };
      },
    };
  }
}

const simple = new SimpleClass([1, 2, 3, 4, 5]);

for (const val of simple) {
  console.log(val); // 1 2 3 4 5
}

Redfinir les itrables intgrs

Par exemple, un objet String est un itrable intgr :

js
const someString = "hi";
console.log(typeof someString[Symbol.iterator]); // "function"

L'itrateur par dfaut de String retourne les points de code de la chane de caractres un par un :

js
const iterator = someString[Symbol.iterator]();
console.log(`${iterator}`); // "[object String Iterator]"

console.log(iterator.next()); // { value: "h", done: false }
console.log(iterator.next()); // { value: "i", done: false }
console.log(iterator.next()); // { value: undefined, done: true }

Vous pouvez redfinir le comportement d'itration en fournissant votre propre [Symbol.iterator]() :

js
// il faut construire explicitement un objet String pour viter l'embotement automatique
const someString = new String("hi");

someString[Symbol.iterator] = function () {
  return {
    // il s'agit de l'objet itrateur, qui retourne un seul lment (la chane "au revoir")
    next() {
      return this._first
        ? { value: "au revoir", done: (this._first = false) }
        : { done: true };
    },
    _first: true,
  };
};

Remarquez comment la redfinition de [Symbol.iterator]() affecte le comportement des constructions intgres qui utilisent le protocole d'itration :

js
console.log([...someString]); // ["au revoir"]
console.log(`${someString}`); // "hi"

Modifications concurrentes lors de l'itration

Presque tous les itrables partagent la mme smantique de base : ils ne copient pas les donnes au moment o l'itration commence. Ils conservent plutt un pointeur et le dplacent. Par consquent, si vous ajoutez, supprimez ou modifiez des lments dans la collection pendant que vous l'itrez, vous risquez involontairement de modifier si d'autres lments inchangs de la collection sont visits. C'est trs similaire au fonctionnement des mthodes itratives de tableau.

Considrez le cas suivant utilisant un URLSearchParams :

js
const searchParams = new URLSearchParams(
  "deleteme1=value1&key2=value2&key3=value3",
);

// Supprimez les cls indsirables
for (const [key, value] of searchParams) {
  console.log(key);
  if (key.startsWith("deleteme")) {
    searchParams.delete(key);
  }
}

// Affiche :
// deleteme1
// key3

Remarquez qu'il n'affiche jamais key2. En effet, un URLSearchParams est, en interne, une liste de paires clvaleur. Lorsque deleteme1 est parcouru puis supprim, toutes les autres entres sont dcales d'une position vers la gauche, de sorte que key2 prend la position qu'occupait deleteme1, et lorsque le pointeur passe la cl suivante, il tombe sur key3.

Certaines implmentations d'itrables vitent ce problme en attribuant des valeurs  tombstone  afin d'empcher le dcalage des valeurs restantes. Considrez le code similaire utilisant une Map :

js
const myMap = new Map([
  ["deleteme1", "value1"],
  ["key2", "value2"],
  ["key3", "value3"],
]);

for (const [key, value] of myMap) {
  console.log(key);
  if (key.startsWith("deleteme")) {
    myMap.delete(key);
  }
}

// Affiche :
// deleteme1
// key2
// key3

Remarquez qu'il affiche toutes les cls. En effet, Map ne dcale pas les cls restantes lorsqu'une cl est supprime. Si vous souhaitez implmenter quelque chose de similaire, voici quoi cela pourrait ressembler :

js
const tombstone = Symbol("tombstone");

class MyIterable {
  #data;
  constructor(data) {
    this.#data = data;
  }
  delete(deletedKey) {
    for (let i = 0; i < this.#data.length; i++) {
      if (this.#data[i][0] === deletedKey) {
        this.#data[i] = tombstone;
        return true;
      }
    }
    return false;
  }
  *[Symbol.iterator]() {
    for (const data of this.#data) {
      if (data !== tombstone) {
        yield data;
      }
    }
  }
}

const myIterable = new MyIterable([
  ["deleteme1", "value1"],
  ["key2", "value2"],
  ["key3", "value3"],
]);
for (const [key, value] of myIterable) {
  console.log(key);
  if (key.startsWith("deleteme")) {
    myIterable.delete(key);
  }
}

Attention : Les modifications concurrentes sont en gnral trs sujettes aux bogues et droutantes. moins de connatre prcisment comment l'itrable est implment, il est prfrable d'viter de modifier la collection pendant que vous l'itrez.

Spcifications

Spcification
ECMAScript 2027 LanguageSpecification
# sec-iteration

Voir aussi


Web Proxy Viewer  |  New URL  |  Original Page