Heim > Web-Frontend > js-Tutorial > Einführung in die Prinzipien von Iteratoren und iterierbaren Objekten in ES6 (mit Beispielen)

Einführung in die Prinzipien von Iteratoren und iterierbaren Objekten in ES6 (mit Beispielen)

不言
Freigeben: 2018-10-29 15:34:36
nach vorne
2639 Leute haben es durchsucht

Dieser Artikel bietet Ihnen eine Einführung in die Prinzipien von Iteratoren und iterierbaren Objekten in ES6 (mit Beispielen). Ich hoffe, dass er Ihnen weiterhilft.

Die neuen Array-Methoden, Sammlungen, for-of-Schleifen, Spread-Operatoren (...) und sogar die asynchrone Programmierung von ES6 basieren alle auf der Implementierung eines Iterators (Iterator). In diesem Artikel werden die Iteratoren und Generatoren von ES6 ausführlich erläutert und die internen Prinzipien und die Verwendung iterierbarer Objekte weiter untersucht

Das Prinzip von Iteratoren

Verarbeitung von Arrays in Programmiersprachen Wenn Sie eine Schleifenanweisung oder eine Sammlung verwenden, müssen Sie eine Variable initialisieren, um die Iterationsposition aufzuzeichnen. Die programmgesteuerte Verwendung von Iteratoren kann diese Datenoperation vereinfachen.

Wie entwerfe ich einen Iterator?

Der Iterator selbst ist ein Objekt. Dieses Objekt verfügt über die next()-Methode, um das Ergebnisobjekt zurückzugeben. Dieses Ergebnisobjekt verfügt über den nächsten Rückgabewert und den booleschen Abschlusswert der Iteration, der das simuliert Erstellung eines einfachen Iterators wie folgt:

Wenn
function createIterator(iterms) {
  let i = 0
  return {
    next() {
      let done = (i >= iterms.length)
      let value = !done ? iterms[i++] : undefined
      return {
        done,
        value
      }
    }
  }
}

let arrayIterator = createIterator([1, 2, 3])

console.log(arrayIterator.next()) // { done: false, value: 1 }
console.log(arrayIterator.next()) // { done: false, value: 2 }
console.log(arrayIterator.next()) // { done: false, value: 3 }
console.log(arrayIterator.next()) // { done: true, value: undefined }
Nach dem Login kopieren
über die obige Syntax verwirrt ist, können Sie sich auf Folgendes beziehen: Ausführliche Erläuterung der neuen Funktionen und destrukturierenden Zuweisung von Objekten in ES6 (Codebeispiele)

Jedes Mal, wenn next() des Iterators aufgerufen wird, wird das nächste Objekt zurückgegeben, bis der Datensatz erschöpft ist.

Die Regeln zum Schreiben von Iteratoren in ES6 sind ähnlich, aber es werden Generatorobjekte eingeführt, um das Erstellen von Iteratorobjekten zu erleichtern

2. Erstellen Sie Iteratoren

ES6 kapselt einen Generator zum Erstellen von Iteratoren. Offensichtlich ist ein Generator eine Funktion, die einen Iterator zurückgibt, der durch ein Sternchen (*) nach der Funktion dargestellt wird, und das neue interne Sonderschlüsselwort yield verwendet, um den Rückgabewert der next()-Methode des Iterators anzugeben.

Wie erstelle ich einen Iterator mit ES6-Generatoren? Ein einfaches Beispiel lautet wie folgt:

function *createIterator() {
  yield 123;
  yield 'someValue'
}

let someIterator = createIterator()

console.log(someIterator.next()) // { value: 123, done: false }
console.log(someIterator.next()) // { value: 'someValue', done: false }
console.log(someIterator.next()) // { value: undefined, done: true }
Nach dem Login kopieren

Mit dem Schlüsselwort yield können Sie jeden Wert oder Ausdruck zurückgeben und Elemente stapelweise zum Iterator hinzufügen:

// let createIterator = function *(items) { // 生成器函数表达式
function *createIterator(items) {
  for (let i = 0; i < items.length; i++) {
    yield items[i]
  }
}

let someIterator = createIterator([123, &#39;someValue&#39;])

console.log(someIterator.next()) // { value: 123, done: false }
console.log(someIterator.next()) // { value: &#39;someValue&#39;, done: false }
console.log(someIterator.next()) // { value: undefined, done: true }
Nach dem Login kopieren

Da es sich um den Generator selbst handelt Als Funktion kann sie dem Objekt hinzugefügt werden und wird wie folgt verwendet:

Eine Funktion der
let obj = {
  // createIterator: function *(items) { // ES5
  *createIterator(items) { // ES6
    for (let i = 0; i < items.length; i++) {
      yield items[i]
    }
  }
}
let someIterator = obj.createIterator([123, &#39;someValue&#39;])
Nach dem Login kopieren
-Generatorfunktion besteht darin, dass die Funktion nach der Ausführung einer Yield-Anweisung und der next()-Methode des Iterators automatisch die Ausführung stoppt wird erneut aufgerufen, um mit der Ausführung der nächsten yield-Anweisung fortzufahren.
Diese Möglichkeit, die Funktionsausführung automatisch abzubrechen, führt zu vielen erweiterten Einsatzmöglichkeiten.

3. Iterierbare Objekte

Häufig verwendete Sammlungsobjekte (Arrays, Set/Map-Sammlungen) und Strings in ES6 sind iterierbare Objekte, und diese Objekte verfügen über Standard-Iteratoren und den Symbol.iterator Eigentum.

Durch Generatoren erstellte Iteratoren sind ebenfalls iterierbare Objekte, da Generatoren der Eigenschaft Symbol.iterator standardmäßig Werte zuweisen.

3.1 Symbol.iterator

Iterierbare Objekte haben die Eigenschaft Symbol.iterator, d. h. Objekte mit der Eigenschaft Symbol.iterator haben Standarditeratoren.

Wir können Symbol.iterator verwenden, um auf den Standarditerator eines Objekts zuzugreifen, beispielsweise für ein Array:

let list = [11, 22, 33]
let iterator = list[Symbol.iterator]()
console.log(iterator.next()) // { value: 11, done: false }
Nach dem Login kopieren

Symbol.iterator ruft den Standarditerator des iterierbaren Objekts des Arrays ab und bearbeitet es. Iteriert über die Elemente im Array.

Im Gegenteil, wir können Symbol.iterator verwenden, um zu erkennen, ob das Objekt ein iterierbares Objekt ist:

function isIterator(obj) {
  return typeof obj[Symbol.iterator] === &#39;function&#39;
}

console.log(isIterator([11, 22, 33])) // true
console.log(isIterator(&#39;sometring&#39;)) // true
console.log(isIterator(new Map())) // true
console.log(isIterator(new Set())) // true
console.log(isIterator(new WeakMap())) // false
console.log(isIterator(new WeakSet())) // false
Nach dem Login kopieren

Offensichtlich sind Arrays, Set/Map-Sammlungen und Strings alle iterierbare Objekte und WeakSet /WeakMap-Sammlungen (schwache Referenzsammlungen) sind nicht iterierbar.

3.2 Iterierbare Objekte erstellen

Benutzerdefinierte Objekte sind standardmäßig nicht iterierbar.

Wie gerade erwähnt, ist der durch den Generator erstellte Iterator auch ein iterierbares Objekt. Der Generator weist der Eigenschaft Symbol.iterator standardmäßig einen Wert zu.

Wie kann man also ein benutzerdefiniertes Objekt in ein iterierbares Objekt umwandeln? Durch Hinzufügen eines Generators zur Eigenschaft Symbol.iterator:

let collection = {
  items: [11,22,33],
  *[Symbol.iterator]() {
    for (let item of this.items){
      yield item
    }
  }
}

console.log(isIterator(collection)) // true

for (let item of collection){
  console.log(item) // 11 22 33
}
Nach dem Login kopieren

Die Array-Elemente sind ein iterierbares Objekt, und das Sammlungsobjekt wird ebenfalls zu einem iterierbaren Objekt, indem der Eigenschaft Symbol.iterator ein Wert zugewiesen wird.

3.3 for-of

Beachten Sie, dass das letzte Beispiel for-of anstelle der Indexschleife verwendet, eine neue Funktion, die von ES6 für iterierbare Objekte hinzugefügt wurde.

Denken Sie über das Implementierungsprinzip der For-Of-Schleife nach.

Für iterierbare Objekte, die for-of verwenden, wird jedes Mal, wenn for-of ausgeführt wird, next() des iterierbaren Objekts aufgerufen und das Rückgabeergebnis in einer Variablen gespeichert. Die Ausführung wird bis zum fortgesetzt iterierbares Objekt Der Wert des done-Attributs ist falsch.

// 迭代一个字符串
let str = &#39;somestring&#39;

for (let item of str){
  console.log(item) // s o m e s t r i n g
}
Nach dem Login kopieren

Im Wesentlichen ruft for-of die Attributmethode Symbol.iterator der Zeichenfolge str auf, um den Iterator zu erhalten (dieser Vorgang wird von der JS-Engine abgeschlossen) und ruft dann zum Speichern mehrmals die Methode next() auf der Objektwert in der Elementvariablen.

Die Verwendung von for-of für nicht iterierbare Objekte, null oder undefiniert, meldet einen Fehler!

3.4 Spread-Operator (...)

Der ES6-Syntax-Zucker-Spread-Operator (...) bedient auch iterierbare Objekte, das heißt, er kann nur Arrays und Sammlungen „verteilen“. , Strings, benutzerdefinierte iterierbare Objekte.

Die folgende Kastanie gibt die von verschiedenen iterierbaren Objekterweiterungsoperatoren berechneten Ergebnisse aus:

let str = &#39;somestring&#39;
console.log(...str) // s o m e s t r i n g
let set = new Set([1, 2, 2, 5, 8, 8, 8, 9])
console.log(set) // Set { 1, 2, 5, 8, 9 }
console.log(...set) // 1 2 5 8 9
let map = new Map([[&#39;name&#39;, &#39;jenny&#39;], [&#39;id&#39;, 123]])
console.log(map) // Map { &#39;name&#39; => 'jenny', 'id' => 123 }
console.log(...map) // [ 'name', 'jenny' ] [ 'id', 123 ]
let num1 = [1, 2, 3], num2 = [7, 8, 9]
console.log([...num1, ...num2]) // [ 1, 2, 3, 7, 8, 9 ]
let udf
console.log(...udf) // TypeError: undefined is not iterable
Nach dem Login kopieren

Wie aus dem obigen Code ersichtlich ist, kann der Erweiterungsoperator (...) iterierbare Objekte bequem konvertieren ein Array. Wie for-of meldet der Spread-Operator (...) einen Fehler, wenn er auf nicht iterierbare Objekte, null oder undefiniert, angewendet wird!

4. Standard-Iterator

ES6 为很多内置对象提供了默认的迭代器,只有当内建的迭代器不能满足需求时才自己创建迭代器。

ES6 的 三个集合对象:Set、Map、Array 都有默认的迭代器,常用的如values()方法、entries()方法都返回一个迭代器,其值区别如下:

entries():多个键值对

values():集合的值

keys():集合的键

调用以上方法都可以得到集合的迭代器,并使用for-of循环,示例如下:

/******** Map ***********/
let map = new Map([['name', 'jenny'], ['id', 123]])

for(let item of map.entries()){
  console.log(item) // [ 'name', 'jenny' ]  [ 'id', 123 ]
}
for(let item of map.keys()){
  console.log(item) // name id
}
for (let item of map.values()) {
  console.log(item) // jenny 123
}

/******** Set ***********/
let set = new Set([1, 4, 4, 5, 5, 5, 6, 6,])

for(let item of set.entries()){
  console.log(item) // [ 1, 1 ] [ 4, 4 ] [ 5, 5 ] [ 6, 6 ]
}

/********* Array **********/
let array = [11, 22, 33]

for(let item of array.entries()){
  console.log(item) // [ 0, 11 ] [ 1, 22 ] [ 2, 33 ]
}
Nach dem Login kopieren

此外 String 和 NodeList 类型都有默认的迭代器,虽然没有提供其它的方法,但可以用for-of循环

Das obige ist der detaillierte Inhalt vonEinführung in die Prinzipien von Iteratoren und iterierbaren Objekten in ES6 (mit Beispielen). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage