Heim  >  Artikel  >  Web-Frontend  >  Kennen Sie iterierbare Objekte und Iteratoren in JavaScript?

Kennen Sie iterierbare Objekte und Iteratoren in JavaScript?

醉折花枝作酒筹
醉折花枝作酒筹nach vorne
2021-08-09 17:53:542650Durchsuche

Iteration ist eine Methode zum Zugriff auf Sammlungselemente. Objekte, die iteriert werden können, werden als iterierbare Objekte bezeichnet. Das Iteratorobjekt beginnt mit dem Zugriff auf das erste Element der Sammlung, bis auf alle Elemente zugegriffen wird , der Iterator kann sich nur vorwärts und nicht rückwärts bewegen.

Verzögerte Auswertung

Verzögerte Auswertung wird oft als „verzögerte Auswertung“ oder „verzögerte Auswertung“ übersetzt, was sich darauf bezieht, den Wert eines Ausdrucks nur dann zu berechnen, wenn er tatsächlich ausgeführt werden muss.

Das Gegenteil der verzögerten Bewertung ist die frühe Bewertung, auch bekannt als gierige Bewertung oder strenge Bewertung, die Bewertungsstrategie der meisten traditionellen Programmiersprachen.

Die Vorteile der vollständigen Nutzung der Merkmale der verzögerten Bewertung spiegeln sich hauptsächlich in den folgenden zwei Aspekten wider:

  • Vermeiden Sie unnötige Berechnungen und verbessern Sie die Leistung.

  • Sparen Sie Platz und ermöglichen Sie Endlosschleifen-Datenstrukturen.

Iteratoren

Iteratoren in ES6 ermöglichen die träge Auswertung und Erstellung benutzerdefinierter Datensequenzen. Iteration ist ein Mechanismus zum Durchlaufen von Daten. Ein Iterator ist ein Zeiger, der zum Durchlaufen der Elemente einer Datenstruktur (ein sogenanntes Iterable) verwendet wird, ein Zeiger, der zum Erzeugen einer Folge von Werten verwendet wird.

Ein Iterator ist ein Objekt, über das iteriert werden kann. Es abstrahiert den Datencontainer, sodass er sich wie ein iterierbares Objekt verhält.

Iteratoren berechnen bei der Instanziierung nicht den Wert jedes Elements und generieren den nächsten Wert erst auf Anfrage. Dies ist insbesondere bei großen Datensätzen oder Folgen unendlicher Elemente sehr nützlich.

Iterierbare Objekte

Iterierbare Objekte sind Datenstrukturen, deren Elemente öffentlich zugänglich sein sollen. Viele Objekte in JS sind iterierbar, sie sind möglicherweise nicht leicht zu erkennen, aber wenn Sie sie sorgfältig untersuchen, werden Sie die Merkmale der Iteration finden:

  • new Map([iterable])

  • new WeakMap([ iterable] )

  • new Set([iterable])

  • new WeakSet([iterable])

  • Promise.all([iterable])

  • Promise.race([iterable])

  • Array.from([iterable])

erfordert auch ein iterierbares Objekt, andernfalls wird ein Typfehler ausgegeben, zum Beispiel:

  • for ... of

  • .. (Operator erweitern). )
    const [a, b, ..] = iterierbar (destrukturierende Zuweisung)

  • yield* (Generator)

Es gibt viele integrierte iterierbare Elemente in JavaScript:

String,Array,TypedArray,Map ,Satz.

Iterationsprotokoll

Iteratoren und iterierbare Objekte folgen dem Iterationsprotokoll.

Ein Protokoll ist eine Reihe von Schnittstellen und legt fest, wie diese verwendet werden.

Iteratoren folgen dem Iterator-Protokoll und Iterables folgen dem Iterable-Protokoll.

Iterierbares Protokoll

Um ein Objekt iterierbar zu machen, muss es eine Iteratormethode über Symbol.iterator implementieren, eine Fabrik für Iteratoren.

Mit TypeScript sieht das iterierbare Protokoll so aus:

interface Iterable {
  [Symbol.iterator]() : Iterator;
}

Symbol.iterator]() ist eine parameterlose Funktion. Wenn wir es für ein iterierbares Objekt aufrufen, können wir über dieses Objekt auf das iterierbare Objekt zugreifen, bei dem es sich um eine reguläre Funktion oder eine Generatorfunktion handeln kann.

Iterator-Protokoll

Das Iterator-Protokoll definiert eine Standardmethode zum Erzeugen einer Folge von Werten.

Damit ein Objekt ein Iterator ist, muss es die next()-Methode implementieren. Iteratoren können die return()-Methode implementieren, die wir später in diesem Artikel besprechen werden.

Unter Verwendung von TypeScript lautet das Iteratorprotokoll wie folgt:

interface Iterator {
    next() : IteratorResult;
    return?(value?: any): IteratorResult;
}

IteratorResult ist wie folgt definiert:

interface IteratorResult {
    value?: any;
    done: boolean;
}
  • done benachrichtigt den Verbraucher, ob der Iterator verwendet wurde, false bedeutet, dass noch ein Wert generiert werden muss, true bedeutet Der Iterator ist beendet.

  • Wert kann ein beliebiger JS-Wert sein, es ist der Wert, der dem Verbraucher angezeigt wird.

Wenn done wahr ist, kann der Wert weggelassen werden.

Kombination

Iteratoren und iterierbare Objekte können durch das folgende Bild dargestellt werden:

Kennen Sie iterierbare Objekte und Iteratoren in JavaScript?

Beispiele

Grundkenntnisse wurden eingeführt, und dann verwenden wir einige Beispiele, um unser Bild zu vertiefen.

Range Iterator

Beginnen wir mit einem sehr einfachen Iterator, dem createRangeIterator-Iterator.

Wir rufen it.next() manuell auf, um das nächste IteratorResult zu erhalten. Der letzte Aufruf gibt {done: true} zurück, was bedeutet, dass der Iterator jetzt verwendet wird und keine Werte mehr produziert.

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());

Kennen Sie iterierbare Objekte und Iteratoren in JavaScript?

Iterable Range Iterator

Zu Beginn dieses Artikels habe ich erwähnt, dass bestimmte Anweisungen in JS ein iterierbares Objekt erfordern. Daher funktioniert unser vorheriges Beispiel nicht, wenn es mit einer for...of-Schleife verwendet wird.

Aber es ist sehr einfach, Objekte zu erstellen, die dem Iterator und den iterierbaren Protokollen entsprechen.

Kennen Sie iterierbare Objekte und Iteratoren in 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)
}

无限序列迭代器

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

注意不要在无限迭代器上使用扩展运算符(...),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
  }
}

Kennen Sie iterierbare Objekte und Iteratoren in 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);
}

Kennen Sie iterierbare Objekte und Iteratoren in JavaScript?

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

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

【推荐学习:javascript高级教程

Das obige ist der detaillierte Inhalt vonKennen Sie iterierbare Objekte und Iteratoren in JavaScript?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen