--- title: function* slug: Web/JavaScript/Reference/Statements/function* translation_of: Web/JavaScript/Reference/Statements/function* ---
הצהרת function* (מילת function ולאחריה כוכבית) מגדירה פונקצית גנרטור, אשר מחזירה אובייקט {{jsxref("Global_Objects/Generator","Generator")}}.
ניתן גם להגדיר פונקציות גנרטור על-ידי שימוש בבנאי {{jsxref("GeneratorFunction")}}, או בתחביר של ביטוי פונקציה.
function* name([param[, param[, ... param]]]) {
statements
}
nameparamstatementsגנרטורים הינם פונקציות שניתן לצאת מהן ולאחר מכן להיכנס אליהן מחדש. ההקשר שלהם (קשירת המשתנים) יישמר לאורך הכניסות מחדש.
גנרטורים ב- JavaScript -- במיוחד בשילוב עם Promises -- הינם כלי חזר מאוד לתכנות אסינכרוני, כיוון שהם מתווכים -- ואפילו מחסלים לחלוטין -- את הבעיות עם קריאות חוזרות, כגון Callback Hell ו- Inversion of Control.
תבנית זו הינה הבסיס לפונקציות async.
קריאה לפונקצית גנרטור לא מריצה את גוף הפונקציה מיידית; במקום זאת, מוחזר אובייקט איטרטור לפונקציה. כאשר המתודה ()next של האיטרטור נקראת, גוף הפונקציה רץ עד לביטוי ה-{{jsxref("Operators/yield", "yield")}} הראשון, אשר מציין את הערך שיוחזר לאיטרטור, או העברה לפונקציה יוצרת אחרת על-ידי שימוש {{jsxref("Operators/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
// ...
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
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 |
|---|---|---|
| {{SpecName('ES2015', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ES2015')}} | הגדרה ראשונית. |
| {{SpecName('ES2016', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ES2016')}} | שונה, כך תהיה מלכודת שבגנרטורים לא [[Construct]] ויזרקו שגיאה בשימוש עם new. |
| {{SpecName('ESDraft', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.statements.generator_function")}}
גרסאות Firefox ישנות יותר מממשות הגדרת גנרטורים ישנה יותר. בגרסה הקודמת גנרטורים הוגדרו על-ידי שימוש במילת function רגילה (ללא כוכבית), בין היתר. ראה פונקציה יוצרת מסורתית למידע נוסף.
IteratorResult מוחזר במקום זריקת שגיאההחל מ- Gecko 29 {{geckoRelease(29)}}, הפונקציה היוצרת המלאה כבר אינה זורקת {{jsxref("TypeError")}} "generator has already finished". במקום זאת, היא מחזירה אובייקט IteratorResult כדוגמת { value: undefined, done: true } ({{bug(958951)}}).