Menu

לולאת for ב-JavaScript: תחביר, דוגמאות, break ו-continue

איך לולאת ה-for הקלאסית עובדת ב-JavaScript: הכותרת בת שלושת החלקים, מעבר על מערכים, break ו-continue, לולאות מקוננות ומלכודות נפוצות.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

לולאת ה-for הקלאסית

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

חמש איטרציות, חמש שורות פלט. נקרא את הכותרת:

  • let i = 0 רץ פעם אחת, לפני שהלולאה מתחילה. הוא מאתחל את המונה.
  • i < 5 נבדק לפני כל איטרציה. אם הוא true, גוף הלולאה רץ. אם הוא false, הלולאה מסתיימת.
  • i++ רץ אחרי כל איטרציה, רגע לפני שהתנאי נבדק שוב.

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

איך החלקים מתחברים

כדאי לעקוב אחרי לולאה אחת ביד כדי לקבע את הסדר:

צעד אחר צעד:

  1. let i = 1: המונה נוצר ומקבל את הערך 1.
  2. בודקים i <= 3: true, אז גוף הלולאה רץ. מודפס 1.
  3. מריצים i++: עכשיו i הוא 2.
  4. בודקים i <= 3: true. מודפס 2.
  5. מריצים i++: עכשיו i הוא 3.
  6. בודקים i <= 3: true. מודפס 3.
  7. מריצים i++: עכשיו i הוא 4.
  8. בודקים i <= 3: false. יוצאים.

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

מעבר על מערך לפי אינדקס

התפקיד הנפוץ ביותר של לולאת for הוא לעבור על מערך. המונה משמש גם כאינדקס:

כמה דברים ששווה לשים לב אליהם:

  • מערכים מתחילים מאינדקס אפס. האיבר הראשון נמצא באינדקס 0, והאחרון ב-length - 1.
  • התנאי הוא i < fruits.length, לא i <= fruits.length. שימוש ב-<= ירוץ צעד אחד אחרי הסוף וידפיס undefined.
  • i מוצהר עם let, ולכן ה-scope שלו הוא הלולאה. מחוץ ללולאה הוא לא קיים.

אם צריך רק את הערכים ולא את האינדקס, for...of קצרה וברורה יותר. נכסה אותה בעמוד משלה.

break: לעצור מוקדם

break יוצא מהלולאה מיד. שימושי כשמצאתם את מה שחיפשתם ואין צורך להמשיך:

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

continue: לדלג על האיטרציה הזו

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

מספרים זוגיים פוגעים ב-continue ומדלגים על ה-console.log. רק האי-זוגיים מודפסים. continue שימושי כשרוצים לסנן איטרציות מסוימות בלי לקנן את שאר גוף הלולאה בתוך if.

צעדים שאינם 1+

שלב העדכון הוא פשוט ביטוי. הוא לא חייב להיות i++. ספירה בקפיצות של שתיים:

ספירה לאחור:

מעבר על מערך מהסוף להתחלה, מה שלפעמים שימושי כשמוחקים איברים תוך כדי:

מה שלא תבחרו, הכלל זהה: התנאי והעדכון צריכים לעבוד יחד כך שהתנאי יהפוך בסוף ל-false. אם לא, הלולאה רצה לנצח. for (let i = 0; i < 10; i--) היא לולאה אינסופית: i זז בכיוון הלא נכון.

לולאות for מקוננות

אפשר לשים לולאת for בתוך לולאה אחרת. הלולאה הפנימית רצה עד הסוף בשביל כל איטרציה של הלולאה החיצונית.

תשע שורות פלט: שלוש איטרציות חיצוניות, ובכל אחת שלוש פנימיות. תנו לכל מונה שם משמעותי (row/col, i/j) במקום להשתמש שוב באותו משתנה.

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

מלכודות נפוצות

כמה דברים שנושכים מתחילים:

שגיאות off-by-one. i <= arr.length רצה צעד אחד יותר מדי, ו-i < arr.length - 1 עוצרת צעד אחד מוקדם מדי. הצורה הסטנדרטית היא i < arr.length.

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

for (let i = 0; i < 10; ) {
    console.log(i); // never ends
}

שימוש ב-var בשביל המונה. ל-var יש scope של פונקציה, אז המונה דולף החוצה מהלולאה ועלול לגרום להפתעות ב-closures. הישארו עם let.

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

מתי לבחור במשהו אחר

לולאת for הקלאסית תמיד זמינה, אבל ל-JavaScript יש אפשרויות קצרות יותר למקרים נפוצים:

  • מעבר על הערכים של מערך: for (const item of array) נקייה יותר.
  • המרה של מערך: array.map(fn) מחזירה מערך חדש.
  • סינון: array.filter(fn).
  • סכימה או צמצום: array.reduce(fn, start).
  • סתם לעשות משהו לכל איבר: array.forEach(fn).

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

הבא בתור: לולאות while

לולאת for מצטיינת כשיודעים את הטווח מראש. כשלא, כשרוצים להמשיך עד שתנאי כלשהו משתנה, while ו-do...while מתאימות יותר. זה העמוד הבא.

שאלות נפוצות

מה התחביר של לולאת for ב-JavaScript?

שלושה חלקים שמופרדים בנקודה-פסיק בתוך סוגריים: for (init; condition; update) { ... }. חלק ה-init רץ פעם אחת, התנאי נבדק לפני כל איטרציה, וחלק העדכון רץ אחרי כל איטרציה. לולאה טיפוסית נראית כך: for (let i = 0; i < 10; i++) { ... }.

איך עוברים על מערך ב-JavaScript?

לולאת for קלאסית עם אינדקס עובדת: for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }. אם לא צריך את האינדקס, for...of נקייה יותר: for (const item of arr) { ... }. להמרה או לסינון, מתודות מערך כמו map ו-filter הן בדרך כלל הכלי הנכון.

איך break ו-continue עובדים בתוך לולאת for?

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

למה לולאת ה-for שלי רצה לנצח?

בדרך כלל כי שלב העדכון אף פעם לא מקרב את התנאי ל-false. for (let i = 0; i < 10; i--) סופרת למטה לנצח, כי i מתחיל ב-0 ורק הופך שלילי יותר. בדקו שוב את התנאי ואת העדכון: הם צריכים לעבוד יחד כך שהתנאי יהפוך בסוף ל-false.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל