Menu

Arrow Functions ב-JavaScript: התחביר =>, this ומתי להשתמש בהן

איך arrow functions עובדות ב-JavaScript: התחביר =>, החזרה מרומזת, איך הן מטפלות ב-this, ומתי לבחור בהן במקום function.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

דרך קצרה יותר לכתוב פונקציה

arrow functions הן התחביר התמציתי של JavaScript להגדרת פונקציה. הן הופיעו ב-ES2015, והיום הן סגנון ברירת המחדל לפונקציות קטנות ומקומיות, במיוחד callbacks שמועברים למתודות מערך, ל-handlers של promises ול-event listeners.

המבנה הוא: פרמטרים, אחריהם =>, ואחריהם הגוף.

אותה תוצאה כמו בצורה הקלאסית:

const add = function (a, b) {
    return a + b;
};

פחות הקלדה זה נחמד, אבל הסיבות האמיתיות להתעניין ב-arrow functions הן ההחזרה המרומזת והאופן שבו הן מתייחסות ל-this. שתיהן מגיעות מיד.

החזרה מרומזת

אם הגוף הוא ביטוי יחיד, אפשר לוותר על הסוגריים המסולסלים ועל ה-return. ערך הביטוי מוחזר אוטומטית:

כאן arrow functions זורחות: טרנספורמציות של שורה אחת נקראות כמו מתמטיקה:

ברגע שצריך יותר מפקודה אחת, חוזרים לסוגריים מסולסלים ול-return מפורש:

שכחה של ה-return בתוך סוגריים מסולסלים היא הטעות הנפוצה ביותר עם arrow functions. x => { x * 2 } מחזירה undefined: הסוגריים הופכים את הגוף לבלוק, והביטוי שבתוכו נזרק.

סוגריים סביב פרמטרים

כשיש בדיוק פרמטר אחד, הסוגריים אופציונליים:

עם אפס, שניים או יותר פרמטרים, צריך אותם:

יש צוותים שמעדיפים תמיד סוגריים לשם עקביות. שני הסגנונות בסדר: בחרו אחד והיצמדו אליו.

החזרה של אובייקט ליטרלי

הנה מלכודת. אם מנסים להחזיר אובייקט במרומז, הסוגריים המסולסלים נראים כמו גוף פונקציה:

זה מדפיס undefined. JavaScript קוראת את { name: name } כבלוק עם פקודה עם תווית, ולא כאובייקט ליטרלי. עטפו את האובייקט בסוגריים עגולים כדי לאלץ אותו להיות ביטוי:

ה-() סביב { ... } הוא הפתרון. זכרו אותו: תיתקלו בזה בשבוע הראשון של כתיבת arrow functions.

this לקסיקלי

הסיבה האמיתית לקיומן של arrow functions היא לא התחביר הקצר. היא שאין להן this משלהן. הן יורשות אותו מהסביבה העוטפת.

כדי לראות למה זה חשוב, נסתכל על פונקציה רגילה שמשמשת כ-callback:

בתוך ה-function () { ... } שמועברת ל-setInterval, this הוא לא counter. פונקציות רגילות מקבלות this משלהן לפי האופן שבו קוראים להן, ו-setInterval קוראת ל-callback כש-this הוא undefined (ב-strict mode) או האובייקט הגלובלי.

arrow function שומרת את ה-this של המתודה העוטפת:

בתוך ה-arrow function, this הוא עדיין counter, כי ה-arrow לא יוצרת this משלה. לפני arrow functions, עקפו את זה עם const self = this; או .bind(this). הדפוסים האלה עדיין עובדים, אבל היום כמעט לא צריך אותם.

מה אין ל-arrow functions

הכלל של this לקסיקלי הוא חלק מדפוס רחב יותר: arrow functions מוותרות על כמה דברים שיש לפונקציות רגילות.

  • אין this משלהן: הוא נורש מהסביבה העוטפת.
  • אין אובייקט arguments: השתמשו בפרמטרי rest (...args) במקומו.
  • אין new: אי אפשר להשתמש ב-arrow function כבנאי.
  • אין מאפיין prototype: נובע מהכלל של אין new.

...args נותן את אותה יכולת "לקבל כל מספר של ארגומנטים" שנתן arguments, עם הבונוס שזה מערך אמיתי. הקריאה new Greeter(...) זורקת שגיאה כי arrow functions הן לא בנאים.

מתי לא להשתמש ב-arrow function

arrow functions הן ברירת המחדל ל-callbacks, אבל הן הבחירה הלא נכונה בכמה מקומות:

מתודות של אובייקט שמוגדרות בתחביר arrow לא מקבלות this שקשור לאובייקט: הן יורשות אותו מהמקום שבו נכתב האובייקט הליטרלי (בדרך כלל הסביבה של המודול או הסביבה הגלובלית). השתמשו בתחביר המתודה המקוצר (greet() { ... }) למתודות.

אותו רעיון חל על מתודות prototype של מחלקות, על מתודות של event handler שצריכות ש-this יתייחס לאלמנט, ועל כל פונקציה שאתם מתכננים לקרוא לה עם new. שם function רגילה היא הכלי הנכון.

כלל אצבע מהיר

  • callback קצר, ביטוי אחד? arrow function.
  • צריכים ש-this יישאר קשור לסביבה החיצונית? arrow function.
  • מגדירים מתודה על אובייקט או על prototype של מחלקה? פונקציה רגילה (או מתודה מקוצרת).
  • כותבים בנאי? פונקציה רגילה, או עדיף, class.

תראו את שני הסגנונות בכל בסיס קוד אמיתי של JavaScript. כדי לדעת איזה מהם מתאים צריך כמה שבועות של קריאת קוד של אחרים, ואחרי זה הבחירה נעשית אוטומטית.

הבא בתור: פרמטרים וערכי ברירת מחדל

ל-arrow functions ולפונקציות רגילות יש אותן יכולות פרמטרים: ערכי ברירת מחדל, פרמטרי rest, ארגומנטים עם destructuring ועוד. זה העמוד הבא, והוא חל על כל צורות הפונקציה שראיתם עד עכשיו.

שאלות נפוצות

מה זו arrow function ב-JavaScript?

arrow function היא דרך קצרה יותר לכתוב פונקציה, עם התחביר =>. const add = (a, b) => a + b; היא arrow function שמקבלת שני ארגומנטים ומחזירה את הסכום שלהם. מעבר לתחביר התמציתי, ל-arrow functions אין this, arguments או super משלהן: הן יורשות אותם מהסביבה העוטפת.

מה ההבדל בין arrow functions לפונקציות רגילות?

לפונקציות רגילות שמוצהרות עם function יש this משלהן, אובייקט arguments משלהן, ואפשר להשתמש בהן כבנאים עם new. ל-arrow functions אין אף אחד מאלה: הן יורשות את this מהמקום שבו הוגדרו. בנוסף, arrow functions לא עוברות hoisting כמו הצהרות פונקציה.

מתי כדאי להשתמש ב-arrow function?

בחרו ב-arrow functions ל-callbacks קצרים (arr.map(x => x * 2)), ובכל מקום שבו אתם רוצים ש-this יישאר קשור לסביבה העוטפת, למשל בתוך מתודה של מחלקה שמעבירה handler ל-setTimeout או ל-event listener. השתמשו ב-function רגילה למתודות של אובייקטים, לבנאים ולפונקציות עצמאיות ברמה העליונה.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל