ביטויי פונקציה

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

const myVariable = function() { };

לאחר מכן תוכלו להפעיל את ביטויי הפונקציות האלה באמצעות מזהה המשתנה:

const myVariable = function() {
    console.log( "This is my function." );
};

myVariable();
> "This is my function."

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

const myVariable = function myFunction() {
    console.log( "This is my function." );
};

myVariable();
> "This is my function."

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

const myVariable = function myFunction() {
  console.log( `I'm a ${ typeof myFunction }.`);
};

typeof myFunction;
> "undefined"

typeof myVariable;
> "function"

myVariable();
> "I'm a function."

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

const myVariable = function myFunction() {
    console.log( "One second elapsed." );
    setTimeout( myFunction, 1000 );
};

setTimeout( myVariable, 1000 );
> "One second elapsed."
> "One second elapsed."
> "One second elapsed."

ביטויים של פונקציית החץ

ביטויים של פונקציות חץ (נקראים בדרך כלל 'פונקציות חץ' או 'lambda') ) היו ב-ES6 כדי לספק תחביר תמציתי ליצירה ביטויי פונקציות אנונימיים עם כמה התנהגויות ייחודיות.

אפשר ליצור פונקציית חץ בכל מקום שבו צפוי ביטוי, למשל כערך שהוקצה למשתנה. בצורתו הנפוצה ביותר, חץ הפונקציה מורכבת מזוג סוגריים תואמים שמכילים אפס או יותר פרמטרים, חץ שמורכב מסימן שווה ומתו 'גדול מ-' (=>), וזוג סוגריים מסולסלים תואמים שמכילים את גוף הפונקציה:

const myFunction = () => {};

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

const myFunction = myParameter => {};

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

const myFunction = () => 2 + 2

myFunction()
> 4

פונקציות החיצים הן ייחודיות כי אין להן הקשר משלהן arguments או this ערכים. במקום זאת, הן יורשים את מפונקציית החץ הסביבה המגבילה ביותר, היא הקרובה ביותר הכרטיסף שמספק את ההקשרים האלה.

function myParentFunction() {
    this.myProperty = true;
    let myFunction = () => {
            console.log( this );
    }
    myFunction();
};

let myInstance = new myParentFunction();
> Object { myProperty: true }

פונקציות של חץ השיחה

פונקציות חיצים לא מקשרות ארגומנטים באותו אופן כמו סוגים אחרים של פונקציות. אובייקט arguments בגוף של פונקציית חץ יורש את הערך שלו מהסביבה הקרובה ביותר שמקיפה את הפונקציה:

function myFunction() {
    let myArrowFunction = () => {
            console.log( arguments[ 0 ] );
    }
    myArrowFunction( true );
};

myFunction( false );
> false

בדוגמה זו, פונקציה חיצונית שנקראה עם הארגומנט false קוראת לפונקציה פונקציית חץ פנימי עם הארגומנט true. כי האובייקט arguments שבתוך פונקציית החץ, הופך לקישור בפונקציה החיצונית, הפונקציה הפנימית רושמת את הפונקציה false של הפונקציה החיצונית.

אם אין אובייקט arguments שצריך לקבל בירושה מההקשר של ההורה, החץ האובייקט arguments של הפונקציה לא מוגדר, וניסיון לגשת אליו גורם שגיאה:

let myArrowFunction = () => {
    console.log(arguments);
};
myArrowFunction( true );
> Uncaught ReferenceError: arguments is not defined

ביטויי פונקציות שמופעלות באופן מיידי (IIFE)

ביטוי פונקציה שמופעלת באופן מיידי (IIFE), שנקרא גם לפעמים "מבצע עצמאי של פונקציה אנונימית", הוא ביטוי של פונקציה שנקרא מיד לאחר הגדרתה. ב-IIFE נעשה שימוש בביטוי פונקציה שנוצר על ידי הכליאת הפונקציה באופרטור קיבוץ. זוג סוגריים נוסף תואם אחר כך מפעיל את הפונקציה, באופן מיידי אחרי הגדרת הפונקציה עצמה או מיד אחרי הקיבוץ . אם משתמשים בפונקציה רגילה, אין הבדל מעשי בין שתי הגישות:

(function() {
    console.log( "IIFE.")
    }
)();
> "IIFE."

(function() {
    console.log( "IIFE.")
    }
());
> "IIFE."

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

עם זאת, יש הבדל כאשר ה-IIFE שלך הוא פונקציית חץ. כאן אותיות רישיות, הסוגריים המשמשים להפעלת הפונקציה חייבים להיות מחוץ לקיבוץ אופרטורים, מכיוון שפונקציית חץ בפני עצמה אינה ביטוי, אבל היא חייבת נוצרות בהקשר שבו נדרש ביטוי. בניסיון לקרוא ל- המשמעות של פונקציית החץ מתוך ההיקף של האופרטורים הקיבוץ קריאה לפונקציית חץ שעדיין לא נוצרה בהקשר של ביטוי:

( () => {
    console.log( "IIFE." );
}() );
> Uncaught SyntaxError: missing ) in parenthetical

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

( () => {
    console.log( "IIFE." );
} )();
> "IIFE."

יישומים מדור קודם, משתמשי IIFE שמשתמשים בהם לעיתים קרובות לניהול היקף, במיוחד כדי להימנע מזיהום ההיקף הגלובלי עם משתנים ברמת הפונקציה והצהרות לגבי פונקציות. לפני השימוש בחסימת היקף ב-ES6, היה מקובל לכווץ סקריפט שלם ב-IIFE כדי למנוע של זיהום מקרי בהיקף גלובלי.

בדיקת ההבנה

האם אפשר לקרוא לביטוי של פונקציה בעלת שם לפי השם מחוץ לפונקציה?

כן
לא