aboutsummaryrefslogtreecommitdiff
path: root/files/he/web/javascript/reference/statements/function_star_/index.html
blob: a72a9278591a6123de2be2cd8742ebfb0e282a48 (plain)
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
201
202
203
204
205
206
207
208
209
210
211
212
---
title: function*
slug: Web/JavaScript/Reference/Statements/function*
translation_of: Web/JavaScript/Reference/Statements/function*
---
<div>{{jsSidebar("Statements")}}</div>

<p> </p>

<p>הצהרת <code><strong>function*</strong></code> (מילת <code>function</code> ולאחריה כוכבית) מגדירה <em>פונקצית גנרטור</em>, אשר מחזירה אובייקט {{jsxref("Global_Objects/Generator","Generator")}}.</p>

<div>{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}</div>



<div class="noinclude">
<p>ניתן גם להגדיר פונקציות גנרטור על-ידי שימוש בבנאי {{jsxref("GeneratorFunction")}}, או בתחביר של ביטוי פונקציה.</p>
</div>

<h2 id="תחביר">תחביר</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>שם הפונקציה.</dd>
</dl>

<dl>
 <dt><code>param</code></dt>
 <dd>השם של פרמטר רשמי של הפונקציה.</dd>
</dl>

<dl>
 <dt><code>statements</code></dt>
 <dd>הפקודות המרכיבות את גוף הפונקציה.</dd>
</dl>

<h2 id="תיאור">תיאור</h2>

<p>גנרטורים הינם פונקציות שניתן לצאת מהן ולאחר מכן להיכנס אליהן מחדש. ההקשר שלהם (קשירת המשתנים) יישמר לאורך הכניסות מחדש.<br>
 <br>
 גנרטורים ב- JavaScript -- במיוחד בשילוב עם Promises -- הינם כלי חזר מאוד לתכנות אסינכרוני, כיוון שהם מתווכים -- ואפילו מחסלים לחלוטין -- את הבעיות עם קריאות חוזרות, כגון <a href="http://callbackhell.com/">Callback Hell</a> ו- <a href="https://frontendmasters.com/courses/rethinking-async-js/callback-problems-inversion-of-control/">Inversion of Control</a>.<br>
 תבנית זו הינה הבסיס לפונקציות <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async</a></code>.</p>

<p>קריאה לפונקצית גנרטור לא מריצה את גוף הפונקציה מיידית; במקום זאת, מוחזר אובייקט <a href="/he/docs/Web/JavaScript/Reference/Iteration_protocols#iterator">איטרטור</a> לפונקציה. כאשר המתודה <code>()next</code> של האיטרטור נקראת, גוף הפונקציה רץ עד לביטוי ה-{{jsxref("Operators/yield", "yield")}} הראשון, אשר מציין את הערך שיוחזר לאיטרטור, או העברה לפונקציה יוצרת אחרת על-ידי שימוש {{jsxref("Operators/yield*", "*yield")}}. מתודת ה- <code>()next</code> מחזירה אובייקט עם שדה <code>value</code>, המכיל את הערך המיוצר ושדה <code>done</code> בכעל ערך בוליאני, המציין האם הגנרטור יצר את הערך האחרון. קריאה למתודת <code>()next</code> עם ארגומנט תמשיך את ריצת פונקציית הגנרטור, תוך החלפת ביטוי ה- <code>yield</code> בו הריצה הופסקה עם הארגומנט מתוך <code>()next</code>.</p>

<p>פקודת <code>return</code> בתוך גנרטור, כאשר הוא רץ, תגרום לגנרטור לסיים (כלומר שדה ה- <code>done</code> המוחזר יהיה בעל <code>true</code>). אם ערך מוחזר, הוא יהיה בשדה <code>value</code> של האובייקט המוחזר על-ידי הגנרטור.<br>
 בדומה לפקודת ה- <code>return</code>, שגיאה שתיזרק בתוך הגנרטור תביא לסיום הגנרטור -- אלא אם היא תיתפס בגוף הגנרטור.<br>
 כאשר גנרטור מסתיים, קריאות נוספות ל- <code>()next</code> לא יגרמו לריצה כלשהי של קוד הגנרטור. הן רק יחזירו אובייקט בצורה זו: <code>{value: undefined, done: true}</code>.</p>

<h2 id="דוגמאות">דוגמאות</h2>

<h3 id="דוגמה_פשוטה">דוגמה פשוטה</h3>

<pre class="brush: js">function* idMaker() {
  var index = 0;
  while (index &lt; 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="דוגמה_עם_*yield">דוגמה עם *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="העברת_ארגומנטים_לגנרטורים">העברת ארגומנטים לגנרטורים</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();

// <span dir="rtl">הקריאה הראשונה ל- next מתבצעת מתחילת הפונקציה</span>
// <span dir="rtl">עד שהיא מגיעה לפקודת yield הראשונה</span>
gen.next();             // 0
gen.next('pretzel');    // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise
</pre>

<h3 id="פקודת_return_בתוך_גנרטור">פקודת return בתוך גנרטור</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="לא_ניתן_ליצור_אובייקט_גנרטור">לא ניתן ליצור אובייקט גנרטור</h3>

<pre class="brush: js">function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor
</pre>

<h3 id="גנרטורים_המוגדרים_בתוך_ביטוי">גנרטורים המוגדרים בתוך ביטוי</h3>

<pre class="brush: js">const foo = function* () {
  yield 10;
  yield 20;
};

const bar = foo();
console.log(bar.next()); // {value: 10, done: false}</pre>

<h2 id="מפרטים">מפרטים</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('ES2015', '#sec-generator-function-definitions', 'function*')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>הגדרה ראשונית.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES2016', '#sec-generator-function-definitions', 'function*')}}</td>
   <td>{{Spec2('ES2016')}}</td>
   <td>שונה, כך  תהיה מלכודת שבגנרטורים לא [[Construct]] ויזרקו שגיאה בשימוש עם <code>new</code>.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-generator-function-definitions', 'function*')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
 </tbody>
</table>

<h2 id="תאימות_לדפדפנים">תאימות לדפדפנים</h2>

<div>


<p>{{Compat("javascript.statements.generator_function")}}</p>
</div>

<h2 id="הערות_ספציפיות_ל-_Firefox">הערות ספציפיות ל- Firefox</h2>

<h4 id="גנרטורים_ואיטרטורים_ב-_Firefox_לפני_גרסה_26">גנרטורים ואיטרטורים ב- Firefox לפני גרסה 26</h4>

<p>גרסאות Firefox ישנות יותר מממשות הגדרת גנרטורים ישנה יותר. בגרסה הקודמת גנרטורים הוגדרו על-ידי שימוש במילת <code>function</code> רגילה (ללא כוכבית), בין היתר. ראה <a href="/he/docs/Web/JavaScript/Reference/Statements/Legacy_generator_function">פונקציה יוצרת מסורתית </a>למידע נוסף.</p>

<h4 id="אובייקט_IteratorResult_מוחזר_במקום_זריקת_שגיאה">אובייקט <code>IteratorResult</code> מוחזר במקום זריקת שגיאה</h4>

<p>החל מ- Gecko 29 {{geckoRelease(29)}}, הפונקציה היוצרת המלאה כבר אינה זורקת {{jsxref("TypeError")}} "generator has already finished". במקום זאת, היא מחזירה אובייקט <code>IteratorResult</code> כדוגמת <code>{ value: undefined, done: true }</code> ({{bug(958951)}}).</p>

<h2 id="ראה_גם">ראה גם</h2>

<ul>
 <li>{{jsxref("Operators/function*", "function* expression")}}</li>
 <li>אובייקט {{jsxref("GeneratorFunction")}}</li>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Iteration protocols</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>Other web resources:
  <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://github.com/mozilla/task.js">Task.js</a></li>
   <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch4.md#iterating-generators-asynchronously">Iterating generators asynchronously</a></li>
  </ul>
 </li>
</ul>