אינטרנט ישראל
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
ראשי » מדריכים » ECMAScript 6 » ECMAScript 6 – לולאת for of

ECMAScript 6 – לולאת for of

רן בר-זיק דצמבר 11, 2016 7:07 am 7 תגובות

על לולאת for of, ההבדל שלה מאיטרטורים אחרים ולמה היא נורא חשובה במקרה של גנרטורים.

המאמר הקודםECMAScript 6 – שמירת מידע ב-Map ו-Set
המאמר הבאECMAScript 6 symbol
כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.

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


var arr = [ 'a', 'b', 'c' ];

for (var i=0; i

יש כמה בעיות עם זה – בראשונה הוא מניח מערך ממוספר מ1 ועד n. אבל אם אין לנו כזה (למשל מערך שבו יש 5 איברים אבל מקום 2 ו-3 חסרים לחלוטין ומקומות 6 עד 7 מאוכלסים) אז הלולאה חסרת ערך לחלוטין.

בדיוק בשביל מקרים כאלו יש לנו את for in שעובד יפה עם מערכים ועם אובייקטים.


var person = {fname:'John', lname:'Doe', age:25}; 

for (var prop in person){
    if (Object.prototype.hasOwnProperty.call(person, prop)){
        console.log(prop+' : '+person[prop]); //"fname : John", "lname : Doe", "age : 25"
    }
}

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


let iterable = [3, 5, 7];
iterable.foo = "hello";

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo"
}

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

יש גם את forEach שהיה אפשר להפעיל אותו על ערכים בלבד. הבעיה איתו שאי אפשר לעצור אותו באמצע הפעולה והוא עובד אך ורק במערך.

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

איך זה עובד? פשוט שבפשוטים:


var arr = ['hello', 'world', 'I', 'am', 'Ran'];

for ( var arrValue of arr ) {
  console.log(arrValue); // 'hello', 'world', 'I', 'am', 'Ran'
}

אם אני אוסיף כל מיני דברים מוזרים למערך (עם או בלי שרשרת פרוטוטייפ) ה-for of יתעלם באלגנטיות. הנה:


var arr = ['hello', 'world', 'I', 'am', 'Ran'];
arr.moshe = 'Levi';

for ( var arrValue of arr ) {
  console.log(arrValue); // 'hello', 'world', 'I', 'am', 'Ran'
}

אפשר לעבור גם על מחרוזות טקסט:


var string = 'hello';

for ( var value of string ) {
  console.log(value); // 'h', 'e', 'l', 'l', 'o'
}

גם בנוגע לאובייקטים יש מעקף נאה שאפשר לעשות:


var obj = { foo : 'hello', bar : 'world' };

for ( var key of Object.keys(obj) ) {
  console.log(key + "->" + obj[key]); // 'foo->hello', 'bar->world'
}

כפי שהבטחתי בהתחלה, אחד הדברים הטובים ב-for of זה שאפשר לשבור אותה באמצע. דבר מעולה כשמדברים על גנרטורים. רוצים דוגמה? הנה:


function* myGenerator() { // a generator function
  var curr = 0;
  while (true) {
    curr++;
    yield curr;
  }
}

for (var n of myGenerator()) {
  console.log(n);
  // truncate the sequence at 100
  if (n >= 100) {
    break;
  }
}

מה קורה פה? יש לנו גנרטור פשוט למדי שעושה איטרציה מ-0 עד אינסוף. בכל איטרציה הוא עושה yield. אני מפעיל את הלולאה for על ה-myGenerator, הלולאה תעבור על כל yield. כיוון שאין לי תנאי עצירה, אני אקבל 1,2,3,4 עד שה-for of יחליט לשבור את הגנרטור. במקרה שלנו כאשר המספר יהיה גדול או שווה למאה.
שימו לב שלא השתמשתי פה ב-next, האיטרטור for of עושה את זה בשבילי.

מסובך? אני אנסה עם דוגמה אחרת:


function* myGenerator() { // a generator function
yield 'a';
yield 'b';
yield 'c';
yield 44;
}

for (var n of myGenerator()) {
  console.log(n); //'a', 'b', 'c', 44
  
}

אולי זה יותר פשוט להבנה, במקום לעשות איזה foreach מגעיל ולעשות next באופן ידני כדי להביא את ה-yield הבא. אני מריץ באמצעות for of את הגנרטור. בכל איטרציה יש לי תוצאה של ה-yield בלי צורך ב-next. אני יכול לשבור את הfor of בכל רגע נתון כמובן עם break.

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

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.
למדריך המלא של ECMAScript 6
ECMAScript 6

7 תגובות

  1. hesk הגב דצמבר 11, 2016 בשעה 2:44 pm

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

  2. אודי אורון הגב דצמבר 12, 2016 בשעה 2:23 pm

    שווה להזכיר שב-ES2017 יכנס Object.entries שאפשר יהיה להשתמש בו כך:

    for (let [k, v] of Object.entries(myObj)) {
    console.log(k, v);
    }

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

    • רן בר-זיק הגב דצמבר 14, 2016 בשעה 6:56 am

      צודק, אך אני אזכיר את זה בסדרת המאמרים על es2017, מבטיח 🙂

  3. מני הגב דצמבר 12, 2016 בשעה 4:11 pm

    "כפי שהבטחתי בהתחלה, אחד הדברים הטובים ב-for in זה שאפשר לשבור אותה באמצע. דבר מעולה כשמדברים על גנרטורים. רוצים דוגמה? הנה:"

    אני חושב שצריך להיות רשום for of

    • רן בר-זיק הגב דצמבר 14, 2016 בשעה 6:57 am

      צודק. תודה רבה שהערת 🙂 יום אחד טעויות ההקלדה האלו יהרגו אותי… :O

  4. משתמש אנונימי (לא מזוהה) הגב ינואר 8, 2017 בשעה 12:54 am

    רן תודה על המאמרים שלך!

  5. מבקר ותיק הגב ינואר 8, 2017 בשעה 12:47 pm

    מעולה !!!

השארת תגובה

ביטול

ללמוד ג'אווהסקריפט בעברית

ללמוד לתכנת ג'אווהסקריפט בעברית שגייס יותר משלוש מאות אלף שקל ולמעלה מ-2000 תומכים - בואו ללמוד עכשיו איך לתכנת.

רשימת הנושאים
  • מדריכים
    • ריאקט
    • טייפסקריפט
    • ECMAScript 6
    • ES20XX
    • Node.js
    • Express
    • רספברי פיי
    • Babel
    • docker
    • MongoDB
    • Git
    • לימוד MySQL
    • SASS
    • jQuery
    • CSS3
    • HTML 5
    • SVN
    • LESS
  • פיתוח אינטרנט
    • פתרונות ומאמרים על פיתוח אינטרנט
    • jQuery Scripts
    • jQuery למתקדמים
    • יסודות בתכנות
    • נגישות אינטרנט
  • חדשות אינטרנט
  • מידע כללי על אינטרנט
    • רשת האינטרנט
    • בניית אתרי אינטרנט
  • rss logo

    לכל המאמרים

    לכל המאמרים שפורסמו באינטרנט ישראל משנת 2008 ועד עכשיו.
  • rss logo

    RSS Feed

    משתמשים בקורא RSS? אם כן, עקבו אחרי אינטרנט ישראל באמצעות פיד ה-RSS!
    מה זה RSS?
  • Twitter logo

    עקבו אחרי בטוויטר

    בחשבון הטוויטר שלי אני מפרסם עדכונים מהירים על חדשות בתחום התכנות והיזמות, התרעות על מצבי חירום ורכילות בוערת על תחום הווב.
    מה זה טוויטר?
  • facebook like image

    ערוץ הטלגרם של אינטרנט ישראל

    בערוץ הטלגרם של אינטרנט ישראל אני מפרסם את הפוסטים של באתר וכן עדכונים טכנולוגיים נוספים.
    מה זה טלגרם?
  • github logo

    הפרויקטים שלי בגיטהאב

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

כל הזכויות שמורות לרן בר-זיק ולאינטרנט ישראל | מדיניות הפרטיות של אתר אינטרנט ישראל | אתר אינטרנט ישראל נגיש לפי תקן WCAG 2.0 AA | הצהרת הנגישות של האתר | אבטחת מידע ודיווח על בעיית אבטחת מידע

גלילה לראש העמוד