1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
---
title: function*
slug: Web/JavaScript/Reference/Statements/function*
tags:
- ECMAScript 2015
- Function
- Iterator
- JavaScript
- Statement
translation_of: Web/JavaScript/Reference/Statements/function*
---
<div>{{jsSidebar("Statements")}}</div>
<p>Die <code><strong>function*</strong></code>-Deklaration ( Schlüsselwort <code>function</code> gefolgt von einem Stern) definiert eine <em>Generatorfunktion</em>, welche ein {{jsxref("Global_Objects/Generator","Generator")}}-Objekt zurückgibt.</p>
<div>{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}</div>
<div class="noinclude">
<p>Eine Generatorfunktion kann auch mittels des {{jsxref("GeneratorFunction")}}-Konstruktors definiert werden.</p>
</div>
<h2 id="Syntax">Syntax</h2>
<pre class="syntaxbox">function* <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>Der Name der Funktion.</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>Der Name eines an die Funktion zu übergebenden Arguments. Eine Funktion kann bis zu 255 Argumente haben.</dd>
</dl>
<dl>
<dt><code>statements</code></dt>
<dd>Die den Körper der Funktion ergebenden Anweisungen.</dd>
</dl>
<h2 id="Beschreibung">Beschreibung</h2>
<p>Generatoren sind Funktionen, die verlassen und später wieder betreten werden können. Ihr Kontext (Variablenbindung) bleibt über die Wiedereintritte hinweg erhalten.</p>
<p>Der Aufruf einer Generatorfunktion führt ihren Körper nicht sofort aus; stattdessen wird ein <a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterator">Iterator</a>-Objekt einer Funktion zurückgegeben. Wenn die <code>next()</code>-Methode des Iterators aufgerufen wird, wird der Körper der Generatorfunktion bis zum ersten {{jsxref("Operators/yield", "yield")}}-Ausdruck ausgeführt, der den vom Iterator zurückzugebenden Wert spezifiziert oder mittels {{jsxref("Operators/yield*", "yield*")}} an eine andere Generatorfunktion weitergibt. Die Methode <code>next()</code> gibt ein Objekt mit einer <code>value</code>-Eigenschaft zurück, die den zurückgegebenen Wert enthält, und eine Eigenschaft <code>done</code>, die anzeigt, ob der Generator seinen letzten Wert zurückgegeben hat (boolescher Wert). Beim Aufrufen der <code>next()</code>-Methode mit einem Argument wird die Generatorfunktion weiter ausgeführt.</p>
<p>Ein <code>return</code>-Statement in einer Generatorfunktion sorgt dafür, dass der Generator fertig ist (Status <code>done</code>). Falls ein Wert zurückgegeben wird, dann wird dieser als <code>value</code> zurückgegeben. Anschließend wird kein weiterer Wert mehr zurückgegeben.</p>
<h2 id="Beispiele">Beispiele</h2>
<h3 id="Einfaches_Beispiel">Einfaches Beispiel</h3>
<pre class="brush: js">function* idMaker(){
var index = 0;
while(index < index+1)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ...</pre>
<h3 id="Beispiel_mit_yield*">Beispiel mit yield*</h3>
<pre class="brush: js">function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
</pre>
<h3 id="Übergeben_von_Argumenten_in_Generatoren">Übergeben von Argumenten in Generatoren</h3>
<pre class="brush: js">function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next(); // 0
gen.next('pretzel'); // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise
</pre>
<h3 id="Return_Statement_in_einem_Generator">Return Statement in einem Generator</h3>
<pre class="brush: js">function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
var gen = yieldAndReturn()
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }
</pre>
<h3 id="Generatoren_haben_keinen_Konstruktor">Generatoren haben keinen Konstruktor</h3>
<pre class="brush: js example-bad">function* f() {}
var obj = new f; // throws "TypeError: f ist kein Konstruktor"</pre>
<h2 id="Spezifikationen">Spezifikationen</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Spezifikation</th>
<th scope="col">Status</th>
<th scope="col">Kommentar</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ES2015', '#', 'function*')}}</td>
<td>{{Spec2('ES2015')}}</td>
<td>Initiale Definition.</td>
</tr>
<tr>
<td>{{SpecName('ES2016', '#', 'function*')}}</td>
<td>{{Spec2('ES2016')}}</td>
<td>Änderung, dass Generatoren nicht über [[Construct]] trap verfügen und eine Ausnahme bei der Verwendung von <code>new</code> erzeugen.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#', 'function*')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
<div>
<p>{{Compat("javascript.statements.generator_function")}}</p>
</div>
<h2 id="Firefox-spezifische_Hinweise">Firefox-spezifische Hinweise</h2>
<h4 id="Generatoren_und_Iteratoren_in_Firefox-Versionen_vor_26">Generatoren und Iteratoren in Firefox-Versionen vor 26</h4>
<p>Ältere Firefox-Versionen implementierten eine ältere Version des Generatorenentwurfs. In den älteren Versionen wurden Generatoren, neben anderen Abweichungen, mit dem normalen Schlüsselwort <code>function</code> (ohne den Stern) definiert. Siehe <a href="/en-US/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">veraltete Generatorfunktion </a>für weitere Informationen.</p>
<h4 id="IteratorResult-Objekt_zurückgegeben_anstatt_Ausnahme_erzeugt"><code>IteratorResult</code>-Objekt zurückgegeben anstatt Ausnahme erzeugt</h4>
<p>Beginnend mit Gecko 29 {{geckoRelease(29)}} erzeugt die ausgeführte Generatorfunktion keine {{jsxref("TypeError")}} "generator has already finished"-Ausnahme mehr. Stattdessen gibt sie <code>ein IteratorResult</code>-Objekt mit <code>{ value: undefined, done: true }</code> ({{bug(958951)}}) zurück.</p>
<h2 id="Siehe_auch">Siehe auch</h2>
<ul>
<li>{{jsxref("Operators/function*", "function* expression")}}</li>
<li>{{jsxref("GeneratorFunction")}} Objekt</li>
<li><a href="/de/docs/Web/JavaScript/Reference/Iteration_protocols">Das Iteratorprotokol</a></li>
<li>{{jsxref("Operators/yield", "yield")}}</li>
<li>{{jsxref("Operators/yield*", "yield*")}}</li>
<li>{{jsxref("Function")}} object</li>
<li>{{jsxref("Statements/function", "function declaration")}}</li>
<li>{{jsxref("Operators/function", "function expression")}}</li>
<li>{{jsxref("Functions_and_function_scope", "Functions and function scope")}}</li>
<li>Andere Quellen im Web:
<ul>
<li><a href="http://facebook.github.io/regenerator/">Regenerator</a> an ES2015 generator compiler to ES5</li>
<li><a href="http://www.youtube.com/watch?v=qbKWsbJ76-s">Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013</a></li>
<li><a href="https://www.youtube.com/watch?v=ZrgEZykBHVo&list=PLuoyIZT5fPlG44bPq50Wgh0INxykdrYX7&index=1">Hemanth.HM: The New gen of *gen(){}</a></li>
<li><a href="http://taskjs.org/">Task.js</a></li>
</ul>
</li>
</ul>
|