aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/iteration_protocols/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/de/web/javascript/reference/iteration_protocols/index.html')
-rw-r--r--files/de/web/javascript/reference/iteration_protocols/index.html349
1 files changed, 349 insertions, 0 deletions
diff --git a/files/de/web/javascript/reference/iteration_protocols/index.html b/files/de/web/javascript/reference/iteration_protocols/index.html
new file mode 100644
index 0000000000..f1ecbe29a1
--- /dev/null
+++ b/files/de/web/javascript/reference/iteration_protocols/index.html
@@ -0,0 +1,349 @@
+---
+title: Iterations Protokolle
+slug: Web/JavaScript/Reference/Iteration_protocols
+tags:
+ - ECMAScript 2015
+ - Intermediate
+ - Iterable
+ - Iterator
+ - JavaScript
+translation_of: Web/JavaScript/Reference/Iteration_protocols
+---
+<div>{{jsSidebar("More")}}</div>
+
+<p>Einige Änderungen in ECMAScript 2015 sind keine neuen Objekte oder Syntax, sondern Protokolle. Diese Protokolle können von jedem Objekt implementiert werden, wenn einige Konventionen eingehalten werden.</p>
+
+<p>Es gibt zwei Protokolle: Das <a href="#Das_Iterierbare_(iterable)_Protokoll">Iterierbare (iterable) Protokoll</a> und das <a href="#Das_Iterator_Protokoll">Iterator Protokoll</a></p>
+
+<h2 id="Das_Iterierbare_iterable_Protokoll">Das Iterierbare (iterable) Protokoll</h2>
+
+<p>Das <strong>Iterierbare (iterable)</strong> Protokoll erlaubt es bei JavaScript-Objekten das Iterierverhalten zu definieren oder anzupassen, wie z. B. wie Werte in einem {{jsxref("Statements/for...of", "for..of")}} Konstrukt durchlaufen werden. Einige Standardtypen sind von sich aus schon Iterierbar mit einem Standarditerationsverhalten, so wie {{jsxref("Array")}} oder {{jsxref("Map")}}, wohingegen andere Typen (so wie {{jsxref("Object")}}) nicht Iterierbar sind.</p>
+
+<p>Um <strong>Iterierbar</strong> zu sein, muss ein Objekt die <strong>@@iterator</strong> Methode implementieren, was bedeutet, dass das Objekte (oder ein Objekt weiter oben in der <a href="/de/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">Prototypenkette</a>) eine Eigenschaft mit dem <strong>@@iterator</strong> Schlüssel haben muss, welcher über die Konstante <code>{{jsxref("Symbol.iterator")}}</code> erreichbar ist:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Eigenschaft</th>
+ <th scope="col">Wert</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>[Symbol.iterator]</code></td>
+ <td>Eine Funktion ohne Parameter, welche ein Objekt zurückgibt, welches dem <a href="#Das_Iterator_Protokoll">Iterator Protokoll</a> entspricht.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Immer wenn ein Objekt iteriert werden soll (z. B. am Anfang einer <code>for..of</code> Schleife), wird die <code>@@iterator</code> Methode mit keinem Argument aufgerufen und der zurückgegebene <strong>Iterator</strong> wird benutzt, um die zu iterierenden Werte zu bekommen.</p>
+
+<h2 id="Das_Iterator_Protokoll">Das Iterator Protokoll</h2>
+
+<p>Das <strong>Iterator</strong> Protokoll definiert einen Standardweg, um eine Sequenz von Werte (endlich oder unendlich lang) zu produzieren.</p>
+
+<p>Ein Objekt ist ein Iterator, wenn es die Methode <code><strong>next()</strong></code> mit folgender Semantik implementiert:</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Eigenschaft</th>
+ <th scope="col"><code>Wert</code></th>
+ </tr>
+ <tr>
+ <td><code>next</code></td>
+ <td>
+ <p>Eine Funktion ohne Parameter, welche ein Objekt mit zwei Eigenschaften zurückgibt:</p>
+
+ <ul>
+ <li><code>done</code> (boolean)
+
+ <ul>
+ <li>Hat den Wert <code>true</code>, wenn der Iterator das Ende der Iterierten Sequenz erreicht hat. In diesem Fall ist <code>value</code> ein optional spezifizierter Rückgabewert des Iterators. Der Rückgabewert ist <a href="http://www.2ality.com/2013/06/iterators-generators.html#generators-as-threads">hier</a> näher erklärt.</li>
+ <li>Hat den Wert <code>false</code>, wenn der Iterator weitere Werte aus der Sequenz produzieren kann. Äquivalent ist, wenn die <code>done</code> Eigenschaft nicht definiert wird.</li>
+ </ul>
+ </li>
+ <li><code>value</code> - ein JavaScript Wert, der vom Iterator zurückgegeben wird. Kann weggelassen werden, wenn <code>done</code> den Wert <code>true</code> hat.</li>
+ </ul>
+
+ <p>Die <code>next</code> Methode gibt immer ein Objekt mit den Eigenschaften <code>done</code> und <code>value</code> zurück. Wird kein Objekt zurückgegeben (wie z. B. <code>false</code> oder <code>undefined</code>), wird ein {{jsxref("TypeError")}} ("iterator.next() returned a non-object value") erzeugt.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Einige Iteratoren sind wiederum iterierbar:</p>
+
+<pre class="brush: js">var someArray = [1, 5, 7];
+var someArrayEntries = someArray.entries();
+
+someArrayEntries.toString(); // "[object Array Iterator]"
+someArrayEntries === someArrayEntries[Symbol.iterator](); // true
+</pre>
+
+<h2 id="Beispiele_für_den_Einsatz_de_Iterations_Protokolle">Beispiele für den Einsatz de Iterations Protokolle</h2>
+
+<p>Ein {{jsxref("String")}} ist ein Beispiel für ein standard iterierbares Objekt:</p>
+
+<pre class="brush: js">var someString = 'hi';
+typeof someString[Symbol.iterator]; // "function"
+</pre>
+
+<p>Der <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator">Standard Iteratior</a> von <code>String</code>s gibt die Codepoints einen nach dem anderen zurück:</p>
+
+<pre class="brush: js">var iterator = someString[Symbol.iterator]();
+iterator + ''; // "[object String Iterator]"
+
+iterator.next(); // { value: "h", done: false }
+iterator.next(); // { value: "i", done: false }
+iterator.next(); // { value: undefined, done: true }</pre>
+
+<p>Einige Standardkonstrukte, wie z. B. die <a href="/de/docs/Web/JavaScript/Reference/Operators/Spread_operator">Spread Syntax</a>, benutzen unter der Decke das selbe Iterierbare Protokoll</p>
+
+<pre class="brush: js">[...someString] // ["h", "i"]</pre>
+
+<p>Man kann das Iterierverhalben neu definieren indem eine eigene <code>@@iterator</code> Eigenschaft definiert wird:</p>
+
+<pre class="brush: js">var someString = new String('hi'); // need to construct a String object explicitly to avoid auto-boxing
+
+someString[Symbol.iterator] = function() {
+ return { // this is the iterator object, returning a single element, the string "bye"
+ next: function() {
+ if (this._first) {
+ this._first = false;
+ return { value: 'bye', done: false };
+ } else {
+ return { done: true };
+ }
+ },
+ _first: true
+ };
+};
+</pre>
+
+<p>Zu bemerken ist, dass die Neudefinition von <code>@@iterator</code> hat Effekte auf Standardkonstrukte, die das Iterierbare Protokoll benutzen;</p>
+
+<pre class="brush: js">[...someString]; // ["bye"]
+someString + ''; // "hi"
+</pre>
+
+<h2 id="Iterierbare_Beispiele">Iterierbare Beispiele</h2>
+
+<h3 id="Standard_iterierbare_Objekte">Standard iterierbare Objekte</h3>
+
+<p>{{jsxref("String")}}, {{jsxref("Array")}}, {{jsxref("TypedArray")}}, {{jsxref("Map")}} und {{jsxref("Set")}} sind im Standard iterierbar, weil jeder Prototyp der Objekte eine <code>@@iterator</code> Methode definiert.</p>
+
+<h3 id="Benutzerdefiniertes_Iterierbares_Objekt">Benutzerdefiniertes Iterierbares Objekt</h3>
+
+<p>Man kann eigene Iterierbare Objekte wie folgt erstellen:</p>
+
+<pre class="brush: js">var myIterable = {};
+myIterable[Symbol.iterator] = function* () {
+ yield 1;
+ yield 2;
+ yield 3;
+};
+[...myIterable]; // [1, 2, 3]
+</pre>
+
+<h3 id="Standard_APIs_akzeptieren_Iterierbare_Objekte">Standard APIs akzeptieren Iterierbare Objekte</h3>
+
+<p>Es gibt viele APIs, die iterierbare Objekte akzeptieren, zum Beispiel: {{jsxref("Map", "Map([iterable])")}}, {{jsxref("WeakMap", "WeakMap([iterable])")}}, {{jsxref("Set", "Set([iterable])")}} and {{jsxref("WeakSet", "WeakSet([iterable])")}}:</p>
+
+<pre class="brush: js">var myObj = {};
+new Map([[1, 'a'], [2, 'b'], [3, 'c']]).get(2); // "b"
+new WeakMap([[{}, 'a'], [myObj, 'b'], [{}, 'c']]).get(myObj); // "b"
+new Set([1, 2, 3]).has(3); // true
+new Set('123').has('2'); // true
+new WeakSet(function* () {
+ yield {};
+ yield myObj;
+ yield {};
+}()).has(myObj); // true
+</pre>
+
+<p>Zudem sollten {{jsxref("Promise.all", "Promise.all(iterable)")}}, {{jsxref("Promise.race", "Promise.race(iterable)")}}, and {{jsxref("Array.from", "Array.from()")}} angeschaut werden.</p>
+
+<h3 id="Syntaxen_die_iterierbare_Objekte_erwarten">Syntaxen die iterierbare Objekte erwarten</h3>
+
+<p>Einige Statements und Ausdrücke erwarten iterierbare Objekt, zum Beispiel die <code><a href="/de/docs/Web/JavaScript/Reference/Statements/for...of">for-of</a></code> Schleife, <a href="/de/docs/Web/JavaScript/Reference/Operators/Spread_operator">Spread Syntax</a>, <code><a href="/de/docs/Web/JavaScript/Reference/Operators/yield*">yield*</a></code> und <a href="/de/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destrukturierende Zuweisungen</a>:</p>
+
+<pre class="brush: js">for(let value of ['a', 'b', 'c']){
+ console.log(value);
+}
+// "a"
+// "b"
+// "c"
+
+[...'abc']; // ["a", "b", "c"]
+
+function* gen() {
+ yield* ['a', 'b', 'c'];
+}
+
+gen().next(); // { value:"a", done:false }
+
+[a, b, c] = new Set(['a', 'b', 'c']);
+a // "a"
+
+</pre>
+
+<h3 id="Nicht_richtig_definierte_iterierbare_Objekte">Nicht richtig definierte iterierbare Objekte</h3>
+
+<p>Wenn eine iterierbare <code>@@iterator</code> Methode keinen Iterator Objekt zurück gibt, ist es nicht richtig definiert. Wenn es so benutzt wird, führt das zu Laufzeitfehlern oder unerwartetem Verhalten:</p>
+
+<pre class="brush: js">var nonWellFormedIterable = {}
+nonWellFormedIterable[Symbol.iterator] = () =&gt; 1
+[...nonWellFormedIterable] // TypeError: [] is not a function
+</pre>
+
+<h2 id="Iterator_Beispiele">Iterator Beispiele</h2>
+
+<h3 id="Einfacher_Iterator">Einfacher Iterator</h3>
+
+<pre class="brush: js">function makeIterator(array) {
+ var nextIndex = 0;
+
+ return {
+ next: function() {
+ return nextIndex &lt; array.length ?
+ {value: array[nextIndex++], done: false} :
+ {done: true};
+ }
+ };
+}
+
+var it = makeIterator(['yo', 'ya']);
+
+console.log(it.next().value); // 'yo'
+console.log(it.next().value); // 'ya'
+console.log(it.next().done); // true
+</pre>
+
+<h3 id="Unendlicher_Iterator">Unendlicher Iterator</h3>
+
+<pre class="brush: js">function idMaker() {
+ var index = 0;
+
+ return {
+ next: function(){
+ return {value: index++, done: false};
+ }
+ };
+}
+
+var it = idMaker();
+
+console.log(it.next().value); // '0'
+console.log(it.next().value); // '1'
+console.log(it.next().value); // '2'
+// ...
+</pre>
+
+<h3 id="Mit_einem_Generator">Mit einem Generator</h3>
+
+<pre class="brush: js">function* makeSimpleGenerator(array) {
+ var nextIndex = 0;
+
+ while (nextIndex &lt; array.length) {
+ yield array[nextIndex++];
+ }
+}
+
+var gen = makeSimpleGenerator(['yo', 'ya']);
+
+console.log(gen.next().value); // 'yo'
+console.log(gen.next().value); // 'ya'
+console.log(gen.next().done); // true
+
+
+
+function* idMaker() {
+ var index = 0;
+ while (true)
+ yield index++;
+}
+
+var gen = idMaker();
+
+console.log(gen.next().value); // '0'
+console.log(gen.next().value); // '1'
+console.log(gen.next().value); // '2'
+// ...
+</pre>
+
+<h3 id="Mit_ES2015_Klassen_class">Mit ES2015 Klassen (class)</h3>
+
+<pre class="brush: js">class SimpleClass {
+ constructor(data) {
+ this.index = 0;
+ this.data = data;
+ }
+
+ [Symbol.iterator]() {
+ return {
+ next: () =&gt; {
+ if (this.index &lt; this.data.length) {
+ return {value: this.data[this.index++], done: false};
+ } else {
+ this.index = 0; //If we would like to iterate over this again without forcing manual update of the index
+ return {done: true};
+ }
+ }
+ }
+ };
+}
+
+const simple = new SimpleClass([1,2,3,4,5]);
+
+for (const val of simple) {
+ console.log(val); //'0' '1' '2' '3' '4' '5'
+}
+</pre>
+
+<h2 id="Ist_ein_Generator_Objekt_ein_Iterator_oder_ein_iterierbares_Objekt">Ist ein Generator Objekt ein Iterator oder ein iterierbares Objekt?</h2>
+
+<p>Ein <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Generator">Generatorobjekt</a> ist beides, Iterator und Iterierbar:</p>
+
+<pre class="brush: js">var aGeneratorObject = function* () {
+ yield 1;
+ yield 2;
+ yield 3;
+}();
+typeof aGeneratorObject.next;
+// "function", because it has a next method, so it's an iterator
+typeof aGeneratorObject[Symbol.iterator];
+// "function", because it has an @@iterator method, so it's an iterable
+aGeneratorObject[Symbol.iterator]() === aGeneratorObject;
+// true, because its @@iterator method returns itself (an iterator), so it's an well-formed iterable
+[...aGeneratorObject];
+// [1, 2, 3]
+</pre>
+
+<h2 id="Spezifikationen">Spezifikationen</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Spezifikation</th>
+ <th scope="col">Status</th>
+ <th scope="col">Kommentar</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES2015', '#sec-iteration', 'Iteration')}}</td>
+ <td>{{Spec2('ES2015')}}</td>
+ <td>Initiale Definition.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-iteration', 'Iteration')}}</td>
+ <td>{{Spec2('ESDraft')}}</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Siehe_auch">Siehe auch</h2>
+
+<ul>
+ <li>Für mehr Informationen über ES2015 Generatoren, siehe <a href="/de/docs/Web/JavaScript/Reference/Statements/function*">die function* Documentation</a>.</li>
+</ul>