פונקציות

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

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

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

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

הצהרות פונקציה

הצהרת פונקציה (שנקראת גם 'הצהרת פונקציה' או 'הגדרת פונקציה') יוצרת פונקציה בעלת שם שאפשר להפעיל במקום אחר בהיקף שמכיל אותה. הצהרות הפונקציה כוללות את מילת המפתח function ואחריה מזהה, רשימה של פרמטרים מופרדים בפסיקים שתחומים בסוגריים, והצהרת בלוק שנקראת "function body". לעיתים קרובות, נתקלים בהצהרות על פונקציות שלא מסתיימות בנקודה ופסיק. בגלל שהצהרת פונקציה היא הצהרה, אפשר להסיק את הסימיקלונים האחרונים באמצעות ASI.

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

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

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

"use strict";
{
    myFunction();
    function myFunction() {
        console.log( "This is my function." );
    };
}
> "This is my function."

מחוץ למצב מחמיר, הצהרות הפונקציות משתמשות בהתנהגות היקף מדור קודם של JavaScript, כלומר הצהרת פונקציה מוגדרת לפונקציה המקיפה הקרובה ביותר שלה:

function myFunction() {
    function myNestedFunction() {
        console.log( "This is my nested function." );
    }
    myNestedFunction();
};

myFunction();
> "This is my nested function."

myNestedFunction();
>Uncaught ReferenceError: myNestedFunction is not defined

במצב מחמיר, הצהרות של פונקציות בהיקף של הבלוק המצורף ביותר, כמו במשתנים שהוצהרו באמצעות let או const:

"use strict";
{
    function myFunction() {
        console.log( "This is my function." );
    };
}

myFunction();
> Uncaught ReferenceError: myFunction is not defined

הפעלת פונקציה

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

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

myFunction;
> myFunction() {
   console.log( "This is my function." );
}

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

function myFunction() {
    console.log( "My function has been executed." );
}

myFunction();
> "My function has been executed."

הפרמטרים בהגדרת הפונקציה פועלים כמשתני placeholder של ערכים שאפשר להעביר לגוף הפונקציה כשהפונקציה נקראת. הערכים בסוגריים כאשר פונקציה מסוימת נקראת 'ארגומנטים' (למרות שיכול להיות שתראו 'ארגומנטים' המשמשים לתיאור ארגומנטים ופרמטרים בחלק מהמסמכים):

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

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

function myFunction( myParameter ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction();
> "The value is: undefined."

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

function myFunction( myParameter = "omitted" ) {
   console.log( `The value is: ${ myParameter }.` );
};

myFunction( "this string" );
> "The value is: this string."

myFunction();
> "The value is: omitted."

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

function myFunction() {
   console.log( arguments );
};

myFunction( 3, true, "My string" );
> Arguments { 0: 3, 1: true, 2: "My string", … }

פונקציות וריאדיות

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

function myFunction() {
    let result = "";
    for (let i = 0; i < arguments.length; i++) {
        result += arguments[i] + " - ";
    }
    console.log( result );
};

myFunction( "My first string", "My second string", "my third string" );\
> "My first string - My second string - my third string - "

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

function myFunction( mySeparator, ...myStrings ) {
  console.log( myStrings.join( mySeparator ) );
};

myFunction( " - ", "My first string", "My second string", "my third string" );
> "My first string - My second string - my third string"

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

function myOuterFunction() {
    let myInnerArrowFunction = ( ...myParams ) => {
        console.log( myParams[ 0 ] );
    }
    myInnerArrowFunction( true );
};

myOuterFunction( false );
> true

let myArrowFunction = ( ...myParams ) => {
    console.log( myParams[ 0 ] );
};

myArrowFunction( true );
> true`
``