תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

פונקציות אנונימיות שקוראות לעצמם ב-javascript

מחבר:
בתאריך:

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

javascript closures

 

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

הדרך הפשוטה לכתוב את הפונקציה כוללת משתנה ברמה הגלובלית (x) ופונקציה add שמוסיפה 1 למשתנה בכל פעם שמריצים אותה.

var x = 0;

function add(){
    x++;
}

add(); // x = 1
add(); // x = 2

 

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

function add(){
    var x = 0;
    return x = x + 1;
}

add(); //1
add(); //1

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

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

var add = (function(){
    var x = 0;
    return function(){ return x = x+1; }
})();

add(); //1
add(); //2

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

למה זה טוב?

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

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

בדוגמה הבאה, הפונקציה car מחזיקה משתנה פרטי model, שניתן לעשות לו set ו-get רק באמצעות פונקציות ציבוריות.

var car = (function car() { 
    var model = 'no model'; 
     return { 
        setModel: function(str) { model = str; }, 
        getModel: function() { return model; }
     }
})();

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

car.model = 'hello';
car.getModel(); // no model

לעומת זאת, אנחנו כן יכולים להשתמש במתודות של האובייקט כדי לעשות set ו-get של המשתנה הפרטי.

car.setModel('sussita');
car.getModel(); // sussita

שימוש אחר נפוץ הוא לסגור קוד בתוך scope משלו שהוא מבודד מהסקופ הגלובלי. לדוגמה, כשכותבים קוד jQuery עוטפים אותו בפונקציה אנונימית שקוראת לעצמה (self invoking anonymous function), ובכך מבודדים אותו מה-window.

(function($){
// קוד jQuery בתוך scope משלו
})(jQuery);

במקרה של jQuery, הפונקציה האנונימית שקוראת לעצמה יוצרת סקופ משל עצמה, וכך מבודדת את הקוד שיושב בתוך הפונקציה מהשפעות הקוד בחוץ.

 

לסיכום

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

מדריכי JavaScript למתקדמים

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

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

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

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

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

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

הוסף תגובה חדשה

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

איך אומרים בעברית אינטרנט?

 

תמונת המגיב

אנונימי בתאריך: 29.10.2018

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

תמונת המגיב

יוסי בן הרוש בתאריך: 29.10.2018

הערה מצוינת. תקנתי. תודה רבה.