Skip to content
בעמוד זה

פונקציות

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

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

javascript
let a = 2;
let b = 4;
b = b * b  * b;
a = a * a * a ;
console.log(a);
console.log(b);

רואים שגם למשתנה a וגם למשתנה b הוצב הערך הנוכחי שלהם בשלושה. כלומר a ו-b בחזקת שלוש. דבר זה נקרא חזרה-מיותרת.

חוץ מזה שחזרה-מיותרת גורמת לכתיבה כפולה של קוד – או הרבה יותר במקרה ומימוש הפעולה קיים במקומות רבים – הוא גם מקשה על שינוי תבנית תכנותית בתוכנה.

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

לשם כך נוצרו פונקציות.

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

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

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

בשתי הדוגמאות העיקרון זהה. אובייקט המקבל מידע מסוג מסוים ומחזיר מידע אחר, מעובד או חדש.

פונקציה נכתבת בתחביר הבא:

javascript
function power(number) {
} 

התחביר מורכב מכמה חלקים

  • המילה שמורה function
  • שם הפונקציה. בדוגמה נקראת power
  • פרמטרים שהפונקציה מקבלת בתוך סוגריים עגולות. בדוגמה פרמטר יחיד בשם number
  • תוכן הפונקציה (החסר בדוגמא) בין הסוגריים המסולסלות

ככה:
function_declreation.svg

פרמטרים הם מידע המועבר לפונקציה בהם היא תשתמש לביצוע סדר הפעולות שלה. פונקציה יכולה לקבל פרמטר אחד או יותר – כמו שהבלנדר יכול לעבוד עם מספר ירקות – או ללא שום פרמטרים כלל – למי לא יצאה פחית חינם ממכונה?

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

javascript
function power(number) {
	return number * number * number;
}

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

javascript
function power(number) {
	return number * number * number;
}

let a = 2;
let b = 4;
b = power(b); 
a = power(b);
console.log(a);
console.log(b);

השורה הבאה מדגימה את השימוש בפונקציות כאשר לאחר אופרטור ההצבה הוצבה הפונקציה power כל ערך שיוחזר מהפונקציה יוצב במשתנה b

javascript
b = power(b);

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

javascript
function power(number) {
	return number * number * number * number;
}

let a = 2;
let b = 4;
b = power(b); 
a = power(b);
console.log(a);
console.log(b);

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

javascript
let board = getChessBoard();
let game  = getChessGame();
playChess(board, game);

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

  • קוד הרבה יותר קריא, כיוון שניתן לתת שמות בעלי משמעות לפונקציות בשונה מסתם פעולה בקוד
  • חלוקת משימות מודולרית – קרי חלוקת אתגרי הפיתוח לפי משימות ותתי משימות. ברגע שמוודאים שפונקציה כתובה כיאות לרוב אין צורך לחזור ולתקן את הקוד שלה בעתיד
  • הסתרת הפעולה – עקרון שלרוב קיים רק ב-OOP (תכנות מונחה עצמים – ילמד בהמשך) אך באמת קיים גם בפונקציות ופרושו שכאשר קטע קוד משתמש בפונקציה הוא אינו מתעניין באופן פעולת הפונקציה. מצידו מדובר בקופסה שחורה קסומה שמקבלת מידע ומחזירה אותו באופן המבוקש.