
Unter Iteration versteht man den Prozess des kontinuierlichen Extrahierens von Daten aus einem Datensatz in einer bestimmten Reihenfolge.
Was ist also der Unterschied zwischen Iteration und Durchquerung?
In JavaScript ist ein Iterator ein Objekt, das next Methode aufrufen kann, um die Iteration durchzuführen gibt ein Objekt mit zwei Eigenschaften zurück.
value : Der nächste Wert des iterierbaren Objektsdone : Gibt an, ob alle Daten abgerufen wurden. false bedeutet, dass noch Daten vorhanden sind, true bedeutet, dass später keine Daten mehr vorhanden sind.um Iteratoren über die Iterator-Factory-Funktion Symbol.iterator im iterierbaren Objekt zu generieren.
const arr = []console.log(arr)

const arr = [1, 2, 3]
const iter1 = arr[Symbol.iterator]() // Einen Iterator über die Iterator-Factory-Funktion „Symbol.iterator“ generieren.
console.log(iter1)
console.log(iter1.next())
console.log(iter1.next())
console.log(iter1.next())
console.log(iter1.next())
console.log('%c%s', 'color:red;font-size:24px;', '================')
const mymap = new Map()
mymap.set('name', 'clz')
mymap.set('age', 21)
const iter2 = mymap[Symbol.iterator]() // Einen Iterator über die Iterator-Factory-Funktion „Symbol.iterator“ generieren.
console.log(iter2)
console.log(iter2.next())
console.log(iter2.next())
console.log(iter2.next())
Es kann festgestellt werden, dass der Iterator abgeschlossen ist, nachdem er den letzten Wert angenommen hat , dh wenn der nächste value des Iterators undefined ist.
Die obige Aussage ist jedoch nicht sehr genau. Sie ist nicht abgeschlossen, wenn der nächste value des Iterators undefined ist. Sie müssen auch feststellen, ob wirklich kein Wert vorhanden ist oder ob das iterierbare Objekt einen Wert enthält, der undefined . Wenn das iterierbare Objekt einen Wert enthält, der undefined ist, wird es zu diesem Zeitpunkt nicht abgeschlossen.
const arr = [1, 2, 3, undefiniert] const iter1 = arr[Symbol.iterator]() // Einen Iterator über die Iterator-Factory-Funktion „Symbol.iterator“ generieren. console.log(iter1) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next())

können die Iterator-Factory-Funktion mehrmals aufrufen, ohne sich gegenseitig zu stören, um mehrere Iteratoren zu generieren. Jeder Iterator stellt eine einmalige geordnete Durchquerung des iterierbaren Objekts dar. Verschiedene Iteratoren stören sich nicht gegenseitig und durchlaufen iterierbare Objekte nur unabhängig voneinander .
const arr = [1, 2, 3]
const iter1 = arr[Symbol.iterator]() // Einen Iterator über die Iterator-Factory-Funktion „Symbol.iterator“ generieren.
const iter2 = arr[Symbol.iterator]()
console.log('Iterator1:', iter1.next())
console.log('Iterator2:', iter2.next())
console.log('Iterator1:', iter1.next())
console.log('Iterator2:', iter2.next())
const arr = [1, 2, 3]
const iter = arr[Symbol.iterator]()
for (const i of iter) {
console.log(i) // 1, 2, 3 nacheinander ausgeben
} Wenn das iterierbare Objekt während der Iteration geändert wird, wird auch das vom Iterator erhaltene Ergebnis geändert.
const arr = [1, 2, 3] console.log(arr) const iter = arr[Symbol.iterator]() console.log(iter.next()) arr[1] = 999 console.log(iter.next()) console.log(iter.next())

Wenn wir zu done: true iterieren, wird beim Aufruf von next ein Fehler gemeldet oder wird nichts zurückgegeben?
Nein, der Iterator befindet sich in einem abgeschlossenen, aber nicht abgeschlossenen Zustand. done: true bedeutet, dass er abgeschlossen wurde, aber next kann weiterhin in der Zukunft aufgerufen werden, obwohl das Ergebnis immer { value: undefined, done: true } ist. . Deshalb sagt man , es sei erledigt, aber nicht erledigt .
const arr = [1, 2, 3] const iter = arr[Symbol.iterator]() console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next())

Aus dem obigen Beispiel können wir erkennen, dass der Iterator durch die Iterator-Factory-Funktion Symbol.iterator generiert wird . Daher müssen wir eine Iterator-Iterator-Factory-Funktion implementieren, und dann kann der Iterator die next Methode aufrufen. Dies ist auch erforderlich Implementieren Sie eine next Methode. Die Iterator-Factory-Funktion gibt die this tatsächlich direkt zurück.
Counter-Beispiel:
class Counter {
Konstruktor(Limit) {
this.count = 1
this.limit = limit }
nächste() {
if (this.count <= this.limit) {
zurückkehren {
erledigt: falsch,
Wert: this.count++
}
} anders {
return { erledigt: wahr, Wert: undefiniert }
}
}
[Symbol.iterator]() {
gib das zurück
}} const counter = neuer Counter(3) const iter = counter[Symbol.iterator]() console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next())

Auf den ersten Blick gibt es kein Problem, aber wenn wir for-of zum Durchqueren verwenden, können wir das Problem finden.
const counter = new Counter(3)for (let i of counter) {
console.log(i)}console.log('Eine weitere Iteration:')for (let i of counter) {
console.log(i)}
Die Verwendung for-of Schleife macht es auch wegwerfbar. Dies liegt daran, dass „ count “ eine Variable dieser Instanz ist und daher in beiden Iterationen dieselbe Variable verwendet wird. Nach der ersten Schleife der Variablen hat sie jedoch den Grenzwert überschritten, sodass Sie bei Verwendung for-of -Schleife nichts erhalten wieder. Das Ergebnis war.
Sie können die count in einen Abschluss einfügen und dann den Iterator über den Abschluss zurückgeben, sodass jeder erstellte Iterator einem neuen Zähler entspricht.
Klassenzähler {
Konstruktor(Limit) {
this.limit = limit }
[Symbol.iterator]() {
lass zählen = 1
const limit = this.limit return {
// Die Iterator-Factory-Funktion muss ein Objekt mit einer nächsten Methode zurückgeben, da die Iteration tatsächlich durch Aufrufen der nächsten Methode implementiert wird next() {
if (count <= limit) {
zurückkehren {
erledigt: falsch,
Wert: count++
}
} anders {
return { erledigt: wahr, Wert: undefiniert }
}
}
}
}} Test
const counter = new Counter(3)for (let i of counter) {
console.log(i)}console.log('Eine weitere Iteration:')for (let i of counter) {
console.log(i)}
ähnelt der Verwendung for-of Schleife. Der Iterator ruft intelligent next Methode auf. Wenn der Iterator vorzeitig beendet wird, ruft er auch die return auf.
[Symbol.iterator]() {
lass zählen = 1
const limit = this.limit return {
// Die Iterator-Factory-Funktion muss ein Objekt mit einer nächsten Methode zurückgeben, da die Iteration tatsächlich durch Aufrufen der nächsten Methode implementiert wird next() {
if (count <= limit) {
zurückkehren {
erledigt: falsch,
Wert: count++
}
} anders {
return { erledigt: wahr, Wert: undefiniert }
}
},
zurückkehren() {
console.log('Beendigung des Iterators vorzeitig')
return { erledigt: true }
}
}} Test
const counter = new Counter(5)for (let i of counter) {
if (i === 3) {
brechen;
}
console.log(i)}
Wenn der Iterator nicht geschlossen ist, können Sie die Iteration dort fortsetzen, wo Sie aufgehört haben . Array-Iteratoren können nicht geschlossen werden.
const arr = [1, 2, 3, 4, 5]const iter = arr[Symbol.iterator]()iter.return = function () {
console.log('Iterator vorzeitig verlassen')
zurückkehren {
erledigt: stimmt
}}for (const i of iter) {
console.log(i)
if (i === 2) {
brechen
}}for (const i of iter) {
console.log(i)}