משתנה לוקלי בפונקציה (JavaScript) האומנם ? – או – הדרך הקלה להיכנס ללואה אינסופית

19 בינואר 2009

תגיות: ,
7 תגובות

 


אתמול ישבה תקוה בורקיס (חברה לעבודה בסלע) וכתבה פונקציות ב JavaScript,

 

באיזשהוא שלב היא אומרת לי, שלמה, אני נכנסת ללולאה אינסופית, מה קורה כאן ?

 אז הסתכלנו על הקוד, ומה שהיה כתוב היה בערך כך:

 

 



    1 <script type="text/javascript">


    2     function f1()


    3     {


    4         for (i = 0; i < 5; i++)


    5         {


    6             // Work…


    7             if (i == 3)


    8             {


    9                 f2();


   10             }


   11         }


   12     }


   13 


   14     function f2()


   15     {


   16         for (i = 0; i < 2; i++)


   17         {


   18             // Work…


   19         }


   20     }


   21 </script>


 

נו.. אל תקראו הלאה, תסתכלו על הקוד ותנסו להבין מה קורה.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

זהו, נשברתם ?

 

הפיתרון מאוד פשוט אבל לא אינטאוטיבי.

 

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

 



    1     function CallCount()


    2     {


    3         if (typeof (count) == "undefined")


    4         {


    5             count = 0;


    6         }


    7 


    8         count++;


    9 


   10         alert(count);


   11     }


 

כמו שאתם רואים, שימוש במשתנה ללא הגדרה של var, יעשה אותו סטטי,

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

 

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

 



    1 <script type="text/javascript">


    2     function f1()


    3     {


    4         for (var i = 0; i < 5; i++)


    5         {


    6             // Work…


    7             if (i == 3)


    8             {


    9                 f2();


   10             }


   11         }


   12     }


   13 


   14     function f2()


   15     {


   16         for (var i = 0; i < 2; i++)


   17         {


   18             // Work…


   19         }


   20     }


   21 </script>


 

שימו לב לשורה 4, 16 להוספת המילה var לפני ההדרה של המשתנה i

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

7 תגובות

  1. TCDooM19 בינואר 2009 ב 16:31

    As far as i understand this is only true since you called the second function (f2) from f1, that way you didn't leave the scope of the i variable… if you leave the scope where you first defined the variable it does go away…

    הגב
  2. Shlomo19 בינואר 2009 ב 16:52

    היי תומר,

    נכון מה שאתה אומר, אבל זה בגלל שאתה שוב משתמש ב i הגלובלי רק במיקום אחר.

    הגב
  3. Avi Pinto19 בינואר 2009 ב 19:46

    זה גיהנום קטן שכמעט כל מי שמתחיל עם javascript נופל אליו בשלב כלשהו.
    שרף לי פעם כמעט יום שלם.

    ודרך אגב – פשוט מדובר במשתנה גלובלי, התנהגות דומה הייתה מתרחשת אם היה מוגדר איפהשהו ב scope הגלובלי – var i
    אז במידה ואין הגדרה חדשה בתוך הפונקציה, אז יהיה שימוש במשתנה זה

    דרך יעילה לעלות על הצרה – כשיש חשד למקרה כזה, אם הקוד נמצא בבלוק אחד – אז אפשר להריץ עליו jslint – פשוט להדביק את הקוד באתר http://www.jslint.com/
    הוא כבר יעיר לך:
    Implied global: i

    פתרון נוסף הינו coding standards – תמיד להתחיל לולאות for ב:
    for (var i = 0;
    (כמובן אם אין אילוץ אחר:)

    הגב
  4. Dvir20 בינואר 2009 ב 9:54

    מה עם
    if (i==3) {
    i=0;
    f2();
    }

    זה גם עוזר, תמיד לאפס את משתנה הבקרה.

    הגב
  5. Shlomo20 בינואר 2009 ב 14:42

    נכון, אבל כמו שב C# לא תעשה את זה, אתה גם לא צריך לעשות את זה ב JS

    הגב
  6. Nir Tayeb30 בינואר 2009 ב 22:47

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

    windows["myGlobalVariable"] = 23;

    אחרת סתם יוצר קוד לא קריא.

    הגב
  7. Shlomo31 בינואר 2009 ב 18:50

    מה שנכון, נכון.

    הגב