--- 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 }
name
param
statements
גנרטורים הינם פונקציות שניתן לצאת מהן ולאחר מכן להיכנס אליהן מחדש. ההקשר שלהם (קשירת המשתנים) יישמר לאורך הכניסות מחדש.
גנרטורים ב- 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)}}).