JavaScript für ungeduldige Programmierer (ES2022-Ausgabe)
Bitte unterstützen Sie dieses Buch: kaufen Sie es oder spenden Sie
(Werbung, bitte nicht blockieren.)

30 Synchrone Iteration



30.1 Worum geht es bei synchroner Iteration?

Synchrone Iteration ist ein Protokoll (Schnittstellen plus Regeln für deren Verwendung), das zwei Gruppen von Entitäten in JavaScript verbindet.

Das Iterationsprotokoll verbindet diese beiden Gruppen über die Schnittstelle Iterable: Datenquellen liefern ihre Inhalte sequentiell „durch sie“; Datenkonsumenten erhalten ihre Eingaben über sie.

Figure 18: Data consumers such as the for-of loop use the interface Iterable. Data sources such as Arrays implement that interface.

Abb. 18 veranschaulicht, wie Iteration funktioniert: Datenkonsumenten verwenden die Schnittstelle Iterable; Datenquellen implementieren sie.

  Die JavaScript-Art, Schnittstellen zu implementieren

In JavaScript implementiert ein Objekt eine Schnittstelle, wenn es über alle Methoden verfügt, die diese beschreibt. Die in diesem Kapitel genannten Schnittstellen existieren nur in der ECMAScript-Spezifikation.

Sowohl Datenquellen als auch -konsumenten profitieren von dieser Regelung.

30.2 Kernkonstrukte der Iteration: Iterables und Iteratoren

Zwei Rollen (beschrieben durch Schnittstellen) bilden den Kern der Iteration (Abb. 19).

Figure 19: Iteration has two main interfaces: Iterable and Iterator. The former has a method that returns the latter.

Dies sind Typdefinitionen (in der Notation von TypeScript) für die Schnittstellen des Iterationsprotokolls.

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

interface Iterator<T> {
  next() : IteratorResult<T>;
}

interface IteratorResult<T> {
  value: T;
  done: boolean;
}

Die Schnittstellen werden wie folgt verwendet:

30.3 Manuelles Iterieren

Dies ist ein Beispiel für die Verwendung des Iterationsprotokolls.

const iterable = ['a', 'b'];

// The iterable is a factory for iterators:
const iterator = iterable[Symbol.iterator]();

// Call .next() until .done is true:
assert.deepEqual(
  iterator.next(), { value: 'a', done: false });
assert.deepEqual(
  iterator.next(), { value: 'b', done: false });
assert.deepEqual(
  iterator.next(), { value: undefined, done: true });

30.3.1 Iterieren über ein Iterable mit while

Der folgende Code zeigt, wie eine while-Schleife verwendet wird, um über ein Iterable zu iterieren.

function logAll(iterable) {
  const iterator = iterable[Symbol.iterator]();
  while (true) {
    const {value, done} = iterator.next();
    if (done) break;
    console.log(value);
  }
}

logAll(['a', 'b']);
// Output:
// 'a'
// 'b'

  Übung: Synchrone Iteration manuell verwenden

exercises/sync-iteration-use/sync_iteration_manually_exrc.mjs

30.4 Iteration in der Praxis

Wir haben gesehen, wie das Iterationsprotokoll manuell verwendet wird, und es ist relativ umständlich. Aber das Protokoll ist nicht dafür gedacht, direkt verwendet zu werden – es ist dafür gedacht, über höherstufige Sprachkonstrukte verwendet zu werden, die darauf aufbauen. Dieser Abschnitt zeigt, wie das aussieht.

30.4.1 Iterieren über Arrays

JavaScript-Arrays sind iterierbar. Das ermöglicht uns die Verwendung der for-of-Schleife.

const myArray = ['a', 'b', 'c'];

for (const x of myArray) {
  console.log(x);
}
// Output:
// 'a'
// 'b'
// 'c'

Die Destrukturierung über Array-Muster (später erklärt) verwendet ebenfalls Iteration im Hintergrund.

const [first, second] = myArray;
assert.equal(first, 'a');
assert.equal(second, 'b');

30.4.2 Iterieren über Sets

Die Set-Datenstruktur von JavaScript ist iterierbar. Das bedeutet, dass for-of funktioniert.

const mySet = new Set().add('a').add('b').add('c');

for (const x of mySet) {
  console.log(x);
}
// Output:
// 'a'
// 'b'
// 'c'

Ebenso wie die Array-Destrukturierung.

const [first, second] = mySet;
assert.equal(first, 'a');
assert.equal(second, 'b');

30.5 Kurzübersicht: Synchrone Iteration

30.5.1 Iterable Datenquellen

Die folgenden integrierten Datenquellen sind iterierbar:

Um über die Eigenschaften von Objekten zu iterieren, benötigen Sie Hilfsmittel wie Object.keys() und Object.entries(). Dies ist notwendig, da Eigenschaften auf einer anderen Ebene existieren, die unabhängig von der Ebene der Datenstrukturen ist.

30.5.2 Synchron iterierende Sprachkonstrukte

Dieser Abschnitt listet Konstrukte auf, die synchrone Iteration verwenden.

30.5.2.1 Iterierende Sprachkonstrukte
30.5.2.2 Iterables in Datenstrukturen umwandeln
30.5.2.3 Sonstiges

  Quiz

Siehe Quiz-App.