Heim > Artikel > Web-Frontend > Iterator ist eine einheitliche Schnittstellenmethode für den Zugriff auf Datensammlungen.
Dieser Artikel stellt Ihnen die einheitliche Schnittstellenmethode für den Zugriff auf die Datenerfassung durch Iterator vor. Freunde in Not können sich darauf beziehen.
TraverserIterator
ist eine einheitliche Schnittstelle, die von ES6 für den Zugriff auf Datensammlungen bereitgestellt wird. Für jede Datensammlung, die über eine intern bereitgestellte Traverser-Schnittstelle verfügt, können Benutzer die entsprechende Datenstruktur auf die gleiche Weise erhalten. Wenn Sie die neueste Version des Chrome
-Browsers verwenden, müssen Sie wissen, dass die uns bekannte Miss Argument stillschweigend einen weiteren Weg zu ihrem Herzen geöffnet hat.
Eine bestimmte Datensammlung stellt die Iterator
-Schnittstelle bereit, was bedeutet, dass ihr Symbol.iterator
-Attribut auf eine Funktion verweist, die die Iterator
-Schnittstelle zurückgibt. Jede Methode, die standardmäßig einen Traverser verwendet, um auf eine Datensammlung zuzugreifen, ruft diese Eigenschaft auf, um das Traverser-Objekt abzurufen, und greift dann in der festgelegten Reihenfolge auf die Mitglieder der Datenstruktur zu (siehe die erweiterte Lektüre im letzten Abschnitt für Symbol.iterator
). . Beispielsweise ist der Traverser eines nativen Arrays [][Symbol.iterator]
, und Array.prototype[Symbol.iterator]
kann auch direkt über den Prototyp seines Konstruktors abgerufen werden.
Der Aufruf der Iterator
-Schnittstelle gibt ein neues Traverser-Objekt (Zeigerobjekt) zurück. Es muss eine
-Methode im next
-Objekt vorhanden sein, die für den Zugriff auf das nächste Datenelement verwendet wird. Der Zeiger zeigt zunächst auf den Anfang der aktuellen Datenstruktur.
Beim ersten Aufruf der next
-Methode des Objekts zeigt der Zeiger auf das erste Mitglied der Datenstruktur.
Beim zweiten Aufruf der next
-Methode des Objekts zeigt der Zeiger auf das zweite Mitglied der Datenstruktur.
Ruft kontinuierlich die next
-Methode des Objekts auf, bis sie auf das Ende der Datenstruktur zeigt.
Jedes Mal, wenn die Methode next
aufgerufen wird, wird dieselbe Datenstruktur zurückgegeben: { value, done }
.
wobei value
den Wert darstellt, der aktuell auf das Mitglied verweist, andernfalls ist es undefined
.
wobei done
ein boolescher Wert ist, der angibt, ob die Durchquerung endet, das Ende ist true
, andernfalls false
.
Der Standard der Traverser-Schnittstelle ist sehr einfach und bietet keine Methoden wie das Betreiben interner Zeiger, das Bestimmen, ob ein Wert vorhanden ist usw. Rufen Sie einfach weiterhin die next
-Methode auf, rufen Sie das aktuelle done
ab, wenn false
value
ist, und stoppen Sie, wenn done
true
ist. Das erste Mal kam ich im Winter 2016 mit dem Verhaltensmuster des Wanderers in Kontakt. Damals hatte ich nicht genügend Hintergrundwissen, um die Anwendbarkeit und Kraft der Einfachheit zu verstehen. Erst jetzt – kurz bevor ich meine Sachen packen und das Unternehmen verlassen musste – bin ich plötzlich aufgewacht. Was für eine schmerzhafte Erkenntnis.
let iterator = [1, 2, 3][Symbol.iterator](); console.log( iterator.next() ); // {value: 1, done: false} console.log( iterator.next() ); // {value: 2, done: false} console.log( iterator.next() ); // {value: 3, done: false} console.log( iterator.next() ); // {value: undefined, done: true}
Für verschiedene Datenstrukturen gibt es verschiedene Traverser-Implementierungsmethoden. Wir implementieren einfach die Array-Traverser-Methode.
let res = null; let iterator = myIterator([3, 7]); console.log( iterator.next() ); // {value: 3, done: false} console.log( iterator.next() ); // {value: 7, done: false} console.log( iterator.next() ); // {value: undefined, done: true} function myIterator(array = []) { let index = 0; return { next() { return index < array.length ? { value: array[index++], done: false } : { value: undefined, done: true }; } }; }
Zusätzlich zur Bereitstellung der next
-Methode für das Traverser-Objekt kann es auch return
- und throw
-Methoden geben. Die return
-Methode wird aufgerufen, wenn die for of
-Schleife vorzeitig verlassen wird (normalerweise aufgrund eines Fehlers oder der Auslösung der break
-Anweisung). Die throw
-Methode wird hauptsächlich in Verbindung mit der Generator
-Funktion verwendet. Allgemeine Traverserobjekte verwenden diese Methode nicht, daher wird sie nicht eingeführt.
let obj = { [Symbol.iterator]() { let index = 0; let array = [1, 2, 3]; return { next() { return index < array.length ? { value: array[index++], done: false } : { value: undefined, done: true }; }, return() { console.log('Trigger return.'); return {}; } }; } }; for (let v of obj) { console.log(v); // 打印出:1, 2, 3,没触发 return 函数。 } for (let v of obj) { if (v === 2) break; console.log(v); // 打印出:1,之后触发 return 函数。 } for (let v of obj) { if (v === 3) break; console.log(v); // 打印出:1, 2,之后触发 return 函数。 } for (let v of obj) { if (v === 4) break; console.log(v); // 打印出:1, 2, 3,没触发 return 函数。 } for (let v of obj) { if (v === 2) throw Error('error'); console.log(v); // 打印出:1,之后触发 return 函数,并报错停止执行。 }
Die Datenstrukturen des nativen Standardinhabers der Traverser-Schnittstelle sind:
Grundtyp: Array
, Set
, Map
(vier Basisdatensätze: Array
, Object
, Set
und Map
).
Array-ähnliche Objekte: arguments
, NodeList
, String
.
let iterator = '123'[Symbol.iterator](); console.log( iterator.next() ); // {value: "1", done: false} console.log( iterator.next() ); // {value: "2", done: false} console.log( iterator.next() ); // {value: "3", done: false} console.log( iterator.next() ); // {value: undefined, done: true}
Traverser und frühere Traversierungsmethoden
Nur weil eine Datensammlung über eine Traverser-Schnittstelle verfügt, heißt das nicht, dass alle Methoden, die sie durchlaufen, diese Schnittstelle verwenden. Tatsächlich werden nur einige neue Methoden und bestimmte in ES6 hinzugefügte Methoden verwendet, die im Folgenden vorgestellt werden. Bei Arrays kann mit for
und for of
auf dieselben Mitglieder zugegriffen werden, die tatsächlichen Vorgänge sind jedoch unterschiedlich.
// 改变数组默认的遍历器接口。 Array.prototype[Symbol.iterator] = function () { let index = 0; let array = this; console.log('Use iterator'); return { next() { return index < array.length ? { value: array[index++], done: false } : { value: undefined, done: true }; } } }; let arr = [1, 2]; for (let v of arr) { console.log(v); // 打印出 Use iterator, 1, 2。 } for (let i = 0; i < arr.length; i++) { console.log(arr[i]); // 打印出 1, 2。 } arr.forEach(d => { console.log(d); // 打印出 1, 2。 });
Das Objekt hat keine Standard-Traverser-Schnittstelle
Warum hat das Objekt keine Standard-Traverser-Schnittstelle? Dies soll unter zwei Gesichtspunkten erklärt werden. Erstens ist der Traverser eine lineare Verarbeitungsstruktur. Für jede nichtlineare Datenstruktur entspricht die Bereitstellung der Traverser-Schnittstelle der Bereitstellung einer linearen Transformation. Zweitens ist das Objekt ursprünglich eine ungeordnete Sammlung. Wenn Sie möchten, dass es geordnet wird, können Sie stattdessen Map
verwenden. Das heißt, jeder hat seine eigenen Stärken und jeder hat seine eigenen Pflichten. Wenn der Mistkäfer nicht die Mistkugel rollt und Honig sammeln geht, kann das Blumenmädchen darunter leiden.
自行生成的类数组对象(拥有length
属性),不具备遍历器接口。这与String
等原生类数组对象不同,毕竟人家是亲生的,一出生就含着金钥匙(也不怕误吞)。不过我们可以将数组的遍历器接口直接应用于自行生成的类数组对象,简单有效无副作用。
let obj = { 0: 'a', 1: 'b', length: 2, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; let iterator = obj[Symbol.iterator](); console.log( iterator.next() ); // {value: "a", done: false} console.log( iterator.next() ); // {value: "b", done: false} console.log( iterator.next() ); // {value: undefined, done: true}
为对象添加遍历器接口,也不影响之前不使用遍历器的方法,比如for in
, Object.keys
等等(两者不等同)。
let obj = { 0: 'a', 1: 'b', length: 2, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; console.log( Object.keys(obj) ); // ["0", "1", "length"] for (let v of obj) { console.log(v); // 依次打印出:"a", "b"。 } for (let k in obj) { console.log(k); // 依次打印出:"0", "1", "length"。 }
for of for of
是专门用来消费遍历器的,其遍历的是键值(for in
遍历的是键名)。
for (let v of [1, 2, 3]) { console.log(v); // 依次打印出:1, 2, 3。 }
扩展运算符
无论是解构赋值或扩展运算都是默认调用遍历器的。
let [...a] = [3, 2, 1]; // [3, 2, 1] let b = [...[3, 2, 1]]; // [3, 2, 1]
yield*
在Generator
函数中有yield*
命令,如果其后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。
for (let v of G()) { console.log(v); // 依次打印出:1, 2, 3, 4, 5 } function* G() { yield 1; yield* [2,3,4]; yield 5; }
其它场合
有些接受数组作为参数的函数,会默认使用数组的遍历器接口,所以也等同于默认调用。比如Array.from()
, Promise.all()
。
相关推荐:
Das obige ist der detaillierte Inhalt vonIterator ist eine einheitliche Schnittstellenmethode für den Zugriff auf Datensammlungen.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!