הצהרת function* (מילת function ולאחריה כוכבית) מגדירה פונקצית גנרטור, אשר מחזירה אובייקט Generator.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
ניתן גם להגדיר פונקציות גנרטור על-ידי שימוש בבנאי GeneratorFunction, או בתחביר של ביטוי פונקציה.
תחביר
function* name([param[, param[, ... param]]]) {
statements
}
name- שם הפונקציה.
param- השם של פרמטר רשמי של הפונקציה.
statements- הפקודות המרכיבות את גוף הפונקציה.
תיאור
גנרטורים הינם פונקציות שניתן לצאת מהן ולאחר מכן להיכנס אליהן מחדש. ההקשר שלהם (קשירת המשתנים) יישמר לאורך הכניסות מחדש.
גנרטורים ב- JavaScript -- במיוחד בשילוב עם Promises -- הינם כלי חזר מאוד לתכנות אסינכרוני, כיוון שהם מתווכים -- ואפילו מחסלים לחלוטין -- את הבעיות עם קריאות חוזרות, כגון Callback Hell ו- Inversion of Control.
תבנית זו הינה הבסיס לפונקציות async.
קריאה לפונקצית גנרטור לא מריצה את גוף הפונקציה מיידית; במקום זאת, מוחזר אובייקט איטרטור לפונקציה. כאשר המתודה ()next של האיטרטור נקראת, גוף הפונקציה רץ עד לביטוי ה-yield הראשון, אשר מציין את הערך שיוחזר לאיטרטור, או העברה לפונקציה יוצרת אחרת על-ידי שימוש *yield. מתודת ה- ()next מחזירה אובייקט עם שדה value, המכיל את הערך המיוצר ושדה done בכעל ערך בוליאני, המציין האם הגנרטור יצר את הערך האחרון. קריאה למתודת ()next עם ארגומנט תמשיך את ריצת פונקציית הגנרטור, תוך החלפת ביטוי ה- yield בו הריצה הופסקה עם הארגומנט מתוך ()next.
פקודת return בתוך גנרטור, כאשר הוא רץ, תגרום לגנרטור לסיים (כלומר שדה ה- done המוחזר יהיה בעל true). אם ערך מוחזר, הוא יהיה בשדה value של האובייקט המוחזר על-ידי הגנרטור.
בדומה לפקודת ה- return, שגיאה שתיזרק בתוך הגנרטור תביא לסיום הגנרטור -- אלא אם היא תיתפס בגוף הגנרטור.
כאשר גנרטור מסתיים, קריאות נוספות ל- ()next לא יגרמו לריצה כלשהי של קוד הגנרטור. הן רק יחזירו אובייקט בצורה זו: {value: undefined, done: true}.
דוגמאות
דוגמה פשוטה
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
// ...
דוגמה עם *yield
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
העברת ארגומנטים לגנרטורים
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
var gen = logGenerator();
// הקריאה הראשונה ל- next מתבצעת מתחילת הפונקציה
// עד שהיא מגיעה לפקודת yield הראשונה
gen.next(); // 0
gen.next('pretzel'); // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise
פקודת return בתוך גנרטור
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 }
לא ניתן ליצור אובייקט גנרטור
function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor
גנרטורים המוגדרים בתוך ביטוי
const foo = function* () {
yield 10;
yield 20;
};
const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
מפרטים
| Specification | Status | Comment |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'function*' in that specification. |
Standard | הגדרה ראשונית. |
| ECMAScript 2016 (ECMA-262) The definition of 'function*' in that specification. |
Standard | שונה, כך תהיה מלכודת שבגנרטורים לא [[Construct]] ויזרקו שגיאה בשימוש עם new. |
| ECMAScript (ECMA-262) The definition of 'function*' in that specification. |
Living Standard |
תאימות לדפדפנים
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function* | Chrome Full support 39 | Edge Full support 13 | Firefox Full support 26 | IE No support No | Opera Full support 26 | Safari Full support 10 | WebView Android Full support 39 | Chrome Android Full support 39 | Firefox Android Full support 26 | Opera Android Full support 26 | Safari iOS Full support 10 | Samsung Internet Android Full support 4.0 | nodejs
Full support
4.0.0
|
IteratorResult object instead of throwing | Chrome Full support 49 | Edge Full support 13 | Firefox Full support 29 | IE No support No | Opera Full support 36 | Safari Full support 10 | WebView Android Full support 49 | Chrome Android Full support 49 | Firefox Android Full support 29 | Opera Android Full support 36 | Safari iOS Full support 10 | Samsung Internet Android Full support 5.0 | nodejs Full support Yes |
Not constructable with new (ES2016) | Chrome Full support 50 | Edge Full support 13 | Firefox Full support 43 | IE No support No | Opera Full support 37 | Safari Full support 10 | WebView Android Full support 50 | Chrome Android Full support 50 | Firefox Android Full support 43 | Opera Android Full support 37 | Safari iOS Full support 10 | Samsung Internet Android Full support 5.0 | nodejs Full support Yes |
| Trailing comma in parameters | Chrome Full support 58 | Edge Full support 14 | Firefox Full support 52 | IE No support No | Opera Full support 45 | Safari Full support 10 | WebView Android Full support 58 | Chrome Android Full support 58 | Firefox Android Full support 52 | Opera Android Full support 43 | Safari iOS Full support 10 | Samsung Internet Android Full support 7.0 | nodejs Full support 8.0.0 |
Legend
- Full support
- Full support
- No support
- No support
- User must explicitly enable this feature.
- User must explicitly enable this feature.
הערות ספציפיות ל- Firefox
גנרטורים ואיטרטורים ב- Firefox לפני גרסה 26
גרסאות Firefox ישנות יותר מממשות הגדרת גנרטורים ישנה יותר. בגרסה הקודמת גנרטורים הוגדרו על-ידי שימוש במילת function רגילה (ללא כוכבית), בין היתר. ראה פונקציה יוצרת מסורתית למידע נוסף.
אובייקט IteratorResult מוחזר במקום זריקת שגיאה
החל מ- Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26), הפונקציה היוצרת המלאה כבר אינה זורקת TypeError "generator has already finished". במקום זאת, היא מחזירה אובייקט IteratorResult כדוגמת { value: undefined, done: true } (bug 958951).
ראה גם
function* expression- אובייקט
GeneratorFunction - Iteration protocols
yield*yieldFunctionobjectfunction declarationfunction expressionFunctions and function scope- Other web resources:
- Regenerator an ES2015 generator compiler to ES5
- Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013
- Task.js
- Iterating generators asynchronously

