Maison > interface Web > js tutoriel > le corps du texte

Connaissez-vous les objets itérables et les itérateurs en JavaScript ?

醉折花枝作酒筹
Libérer: 2021-08-09 18:02:03
avant
2618 Les gens l'ont consulté

L'itération est une méthode d'accès aux éléments de la collection ; les objets qui peuvent être itérés sont appelés objets itérables ; un itérateur est un objet qui peut mémoriser la position de traversée. L'objet itérateur commence à accéder à partir du premier élément de la collection jusqu'à ce que tous les éléments aient été accédés. , l'itérateur ne peut qu'avancer et non reculer.

Évaluation paresseuse

L'évaluation paresseuse est souvent traduite par « évaluation paresseuse » ou « évaluation paresseuse », qui fait référence au calcul de la valeur d'une expression uniquement lorsqu'elle doit réellement être exécutée.

Le contraire de l'évaluation paresseuse est l'évaluation précoce, également connue sous le nom d'évaluation gourmande ou d'évaluation stricte, est la stratégie d'évaluation de la plupart des langages de programmation traditionnels.

Les avantages de tirer pleinement parti des caractéristiques de l'évaluation paresseuse se reflètent principalement dans les deux aspects suivants :

  • Éviter les calculs inutiles et améliorer les performances.

  • Économisez de l'espace et rendez possibles des structures de données en boucle infinie.

Itérateurs

Les itérateurs dans ES6 permettent d'évaluer et de créer paresseusement des séquences de données définies par l'utilisateur. L'itération est un mécanisme de parcours de données. Un itérateur est un pointeur utilisé pour parcourir les éléments d'une structure de données (appelé Iterable), un pointeur utilisé pour produire une séquence de valeurs.

Un itérateur est un objet qui peut être itéré. Il fait abstraction du conteneur de données afin qu'il se comporte comme un objet itérable.

Les itérateurs ne calculent pas la valeur de chaque élément lorsqu'ils sont instanciés et génèrent uniquement la valeur suivante lorsque cela est demandé. Ceci est très utile, en particulier pour les grands ensembles de données ou les séquences d'éléments infinis.

Objets itérables

Les objets itérables sont des structures de données qui souhaitent que leurs éléments soient accessibles publiquement. De nombreux objets en JS sont itérables. Ils peuvent ne pas être faciles à détecter, mais si vous examinez attentivement, vous trouverez les caractéristiques de l'itération :

  • new Map([iterable])

  • new WeakMap([ itérable] )

  • new Set([iterable])

  • new WeakSet([iterable])

  • Promise.all([iterable])

  • Promise.race([iterable])

  • Array.from([iterable])

nécessite également un objet itérable, sinon, il générera une erreur de type, par exemple :

  • for ... of

  • .. (opérateur d'expansion. )
    const [a, b, ..] = itérable (affectation de déstructuration)

  • yield* (générateur)

Il existe de nombreux éléments itérables intégrés en JavaScript :

String,Array,TypedArray,Map ,Ensemble.

Protocole d'itération

Les itérateurs et les objets itérables suivent le protocole d'itération.

Un protocole est un ensemble d'interfaces et précise comment les utiliser.

Les itérateurs suivent le protocole itérateur et les itérables suivent le protocole itérable.

Protocole itérable

Pour rendre un objet itérable, il doit implémenter une méthode itérateur via Symbol.iterator, qui est une usine pour les itérateurs.

En utilisant TypeScript, le protocole itérable ressemble à ceci :

interface Iterable {
  [Symbol.iterator]() : Iterator;
}
Copier après la connexion

Symbol.iterator]() est une fonction sans paramètre. L'appeler sur un objet itérable signifie que nous pouvons accéder à l'objet itérable via cela, qui peut être une fonction régulière ou une fonction génératrice.

Iterator Protocol

Le protocole itérateur définit une manière standard de produire une séquence de valeurs.

Pour qu'un objet soit un itérateur, il doit implémenter la méthode next(). Les itérateurs peuvent implémenter la méthode return(), dont nous parlerons plus loin dans cet article.

En utilisant TypeScript, le protocole de l'itérateur est le suivant :

interface Iterator {
    next() : IteratorResult;
    return?(value?: any): IteratorResult;
}
Copier après la connexion

IteratorResult est défini comme suit :

interface IteratorResult {
    value?: any;
    done: boolean;
}
Copier après la connexion
  • done informe le consommateur si l'itérateur a été utilisé, false signifie qu'il y a encore une valeur à générer, true signifie l'itérateur est terminé.

  • value peut être n'importe quelle valeur JS, c'est la valeur affichée au consommateur.

Lorsque cela est vrai, la valeur peut être omise.

combination

Les itérateurs et les objets itérables peuvent être représentés par l'image suivante :

Connaissez-vous les objets itérables et les itérateurs en JavaScript ?

Exemples

Les connaissances de base ont été introduites, puis utilisons quelques exemples pour approfondir notre image.

Range Iterator

Commençons par un itérateur très basique, l'itérateur createRangeIterator.

Nous appelons manuellement it.next() pour obtenir le prochain IteratorResult. Le dernier appel renvoie {done: true}, ce qui signifie que l'itérateur est désormais utilisé et ne produit plus de valeurs.

function createRangeIterator(from, to) {
  let i = from;

  return {
    next() {
      if (i <= to) {
        return { value: i++, done: false };
      } else {
        return { done: true };
      }
    }
  }
}

const it = createRangeIterator(1, 3);

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
Copier après la connexion

Connaissez-vous les objets itérables et les itérateurs en JavaScript ?

Iterable Range Iterator

Plus tôt dans cet article, j'ai mentionné que certaines instructions en JS nécessitent un objet itérable. Par conséquent, notre exemple précédent ne fonctionnera pas lorsqu’il est utilisé avec une boucle for...of.

Mais il est très facile de créer des objets conformes à l'itérateur et aux protocoles itérables.

Connaissez-vous les objets itérables et les itérateurs en JavaScript ?

function createRangeIterator (from, to) {
  let i = from

  return {
    [Symbol.iterator] () {
      return this
    },
    next() {
      if (i <= to) {
        return { value: i++, done: false }
      } else {
        return { done: true }
      }
    }
  }
}

const it = createRangeIterator(1, 3)

for (const i of it) {
  console.log(i)
}
Copier après la connexion

无限序列迭代器

迭代器可以表示无限制大小的序列,因为它们仅在需要时才计算值。

注意不要在无限迭代器上使用扩展运算符(...),JS 将尝试消费迭代器,由于迭代器是无限的,因此它将永远不会结束。 所以你的应用程序将崩溃,因为内存已被耗尽

同样,for ... of 循环也是一样的情况,所以要确保能退出循环:

function createEvenNumbersIterator () {
  let value = 0

  return {
    [Symbol.iterator] () {
      return this
    },
    next () {
      value += 2
      return { value, done: false}
    }
  }
}

const it = createEvenNumbersIterator()

const [a, b, c] = it
console.log({a, b, c})

const [x, y, z] = it
console.log({ x, y, z })

for (const even of it) {
  console.log(even)
  if (even > 20) {
    break
  }
}
Copier après la connexion

Connaissez-vous les objets itérables et les itérateurs en JavaScript ?

关闭迭代器

前面我们提到过,迭代器可以有选择地使用return()方法。 当迭代器直到最后都没有迭代时使用此方法,并让迭代器进行清理。

for ... of循环可以通过以下方式更早地终止迭代:

  • break

  • continue

  • throw

  • return

function createCloseableIterator () {
  let idx = 0
  const data = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;]

  function cleanup() {
    console.log(&#39;Performing cleanup&#39;)
  }
  return {
    [Symbol.iterator]() { return this },
    next () {
      if (idx <= data.length - 1) {
        return { value: data[idx++], done: false }
      } else {
        cleanup()
        return { done: true }
      }
    },
    return () {
      cleanup()
      return { done: true }
    }
  }
}

const it = createCloseableIterator()

for (const value of it) {
  console.log(value)
  if (value === &#39;c&#39;) {
    break
  }
}

console.log(&#39;\n----------\n&#39;)

const _it = createCloseableIterator();
for (const value of _it) {
  console.log(value);
}
Copier après la connexion

Connaissez-vous les objets itérables et les itérateurs en JavaScript ?

  • 如果知道迭代器已经结束,则手动调用cleanup()函数。

  • 如果突然完成,则return()起作用并为我们进行清理。

【推荐学习:javascript高级教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!