Javascript
Javascript: לולאות ושאר ירקות, על For…in ועל For…of
הלולאה הכי בסיסית ב-Javascript (וכמעט בכל שפת תכנות) היא לולאת ה-for, הלולאה מקבלת שלושה ביטויים: הצהרה על משתנה, ביטוי שיש להעריך לפני כל איטרציה וביטוי שיש להעריך בסוף כל איטרציה.
הדוגמא הבא מציגה לולאת for פשוטה המדפיסה את האיברים במערך:
const arr = ['א', 'ב', 'ג', 'ד'];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// הלולאה מדפיסה: א, ב, ג, ד
אין שום דבר רע בלולאה ה-for הרגילה, אך זה מרגיש שאנחנו צריכים לרשום הרבה קוד על מנת להשיג משהו כל-כך פשוט כמו לולאה.
- אנחנו צריכים לעקוב אחרי משתנה ה-i ולעלות אותו באחד אחרי כל איטרציה (i++)
- להצהיר על תנאי עצירה (i < arr.length)
- לפנות אל הערך הנוכחי בשילוב של שני משתנים (arr[i])
אומנם אנחנו יכולים לכתוב את הקוד למעלה בצורה יעילה ונקייה יותר, אך זה עדיין לא נוח מספיק ביחס לאלטרנטיבות:
const arr = [55, 32, 25, 78, 95];
const length = arr.length;
for (let i = 0; i < length; i++) {
console.log(arr[i]);
}
בשפת Javascrpt יש לנו אלטרנטיבות נוספות לביצוע איטרציות, היום אנחנו נכיר שניים מהם, את לולאת ה-For…in ואת לולאת ה-For…of ומה ההבדלים בינהם.
לולאת For…in
לולאת ה-for…in מבצעת איטרציה על enumerable properties של אובייקט, ההגדרה של Enumerable property היא ערך חיובי בשדה Enumerable של-Property.
בואו נדגים איך אפשר לבדוק בצורה פשוטה אם Property מסויים הוא Enumerable:
let obj = {
type: "Car",
year: "2018",
brand: "Audi"
};
Object.getOwnPropertyDescriptor(obj, 'type')
במידה ונדביק את הקוד למעלה ב- Console אנחנו נקבל את הפלט הבא:

בעזרת Object.getOwnPropertyDescriptor אנחנו יכולים לדעת אם property הוא enumerable או לא.
התחביר של לולאת ה-for…in הוא:
for (varush in enumerable) {
// do stuff
}
לדוגמא, אם נרצה להדפיס את כל הערכים של אובייקט מסויים, אנחנו נוכל לכתוב:
const arr = [1, 2, 3, 4];
for (const key in arr) {
console.log(obj[key])
}
// הלולאה מדפיסה: 1, 2, 3, 4
לולאת ה-for..in מבצעת איטרציה על כל ה-enumerable properties של האובייקט גם כאלה שנמצאים ב-prototype, אם נרצה למנוע מצב מסוג זה נוכל להשתמש ב- hasOwnProperty בצורה הבאה:
const obj = { g: 4, h: 8, j: 9, t: 0, d: 5 }
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// do stuff
}
}
חשוב להדגיש שלולאת ה-for…in מבצעת את האיטרציות בצורה שרירותית כך שאל תשתמשו בלולאה הזאת אם אתם צריכים שהדברים יתבצעו בסדר שהם הוגדרו.
לולאת For…of
לולאת ה-for…of הגיעה אלינו יחד עם ES6 והיעוד שלה הוא לבצע איטרציות על סוגים שונים של אוספים (collections) כמו Arrays, strings, Maps, Set, NodeList, TypedArray, אלו אובייקטים שמכילים Property בשם [Symbol.iterator].
ה-[Symbol.iterator] מאפשר לנו לבצע איטרציה בצורה ידנית על ידי קריאה ל:
[Symbol.iterator]().next()
על מנת לקבל את הערך הבא באוסף, בואו נדגים:
const array = ['M', 'e', 'n', 'i'];
const iterator = array[Symbol.iterator]();
console.log(iterator.next().value)
console.log(iterator.next().value)
console.log(iterator.next().value)
console.log(iterator.next().value)
// הלולאה מדפיסה: M, e, n, i
לולאת ה-For…of היא למעשה מעטפת סביב ה-[Symbol.iterator] על מנת ליצור לולאות, For…of משתמשת בתחביר הבא:
for (varush of iterable) {
// do stuff
}
לולאת ה-For…of לא יכולה לעבוד עם אובייקטים מאחר והם לא "iterable" וכתוצאה מכך אין להם את ה-Property שבו הלולאה משתמשת שהוא ה-[Symbol.iterator].
בואו נסתכל על מספר דוגמאות של מקרים שלולאת ה-For..of יכולה לעזור לנו:
// מערך
const array = ['M', 'e', 'n', 'i'];
for (const item of array) {
console.log(item)
}
// הלולאה מדפיסה: M, e, n, i
// מחרוזת
const string = 'CodeHub';
for (const character of string) {
console.log(character)
}
// הלולאה מדפיסה: C, o, d, e, H, u, b
// אוסף NodeList
const elements = document.querySelectorAll('.menu');
for (const element of elements) {
element.addEventListener('click', handleMenuClick);
}
