אוספים עם מפתח

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

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

כדי ליצור מפה, משתמשים ב-constructor של Map():

const myMap = new Map();

myMap;
> Map(0)

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

const myMap = new Map([
    [ "myKey", "A string value" ],
    [ "mySecondKey", 500 ],
    [ "myThirdKey", true ]
]);

myMap;
> Map(3) {'myKey' => 'A string value', 'mySecondKey' => 500, 'myThirdKey' => true}

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

const notAFunction = () => console.log( "function" );
const myMap = new Map([
  [ null, 0 ],
  [ false, "This is false" ],
  [ undefined, "No defined value" ],
  [ NaN, "Not a number" ]
]);

myMap;
> Map(4) {null => 0, false => 'This is false', undefined => 'No defined value', NaN => 'Not a number'}

כדי לקבל, להגדיר או למחוק רכיבי מפה, צריך להשתמש בשיטות שעברו בירושה מMap constructor:

const myMap = new Map();

myMap;
> Map(0)

myMap.set( "myKey", "My value." );

myMap.has( "myKey" );
> true

myMap.get( "myKey" );
"My value."

myMap.delete( "myKey" );

myMap;
> Map(0)

מפתחות במפה הם ייחודיים, כלומר, הגדרת מפתח זהה מחליפה את צמד מפתח/ערך שנשמר בעבר:

const myMap = new Map([ [ "myKey", "A string value" ] ]);

myMap.set( "myKey", 500 );

myMap;
> Map(1) {'myKey' => 500}

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

const myMap = new Map();
myMap.set( "myKey", "A string value" );

myMap;
> Map(1) {'myKey' => 500}

WeakMap

WeakMap היא מפה שמכילה "חלש" reference, שחייב להיות הפניות לאובייקטים או לסמלים שלא נוספו למרשם הסמלים הגלובלי.

כדי ליצור WeakMap, משתמשים ב-constructor של WeakMap():

const myWeakMap = new WeakMap();

myWeakMap;
> WeakMap(0)

התחביר של WeakMap דומה לתחביר של Map, אבל התחביר של WeakMaps אינו דומה שאפשר לחזור עליו, ולנסות להשתמש בו כל ערך מלבד אובייקט או סמל כמפתח גורם לשגיאת תחביר. כשלא קיימות הפניות למפתח מסוים מחוץ ל-WeakMap, האובייקט או הסמל, והערך המשויך WeakMap, שתי האפשרויות כשירות לאיסוף אשפה.

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

סיום

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

כדי ליצור קבוצה, משתמשים ב-constructor של Set():

const mySet = new Set();

mySet;
> Set []

תוכלו גם ליצור סדרה מליטרל של מערך:

const mySet = new Set([ 1, 2, 3 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

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

const mySet = new Set([ 1, 2, 3, 2 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

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

const mySet = new Set();

mySet.add( "My value." );

mySet;
> Set [ "My value." ]

mySet.has( "My value." );
> true

mySet.delete( "My value." );

mySet;
> Set []

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

const mySet = new Set([ 1, 2, 3 ]);

mySet;
> Set(3) [ 1, 2, 3 ]

mySet.add( 2 );
> Set(3) [ 1, 2, 3 ]

כדי ליצור מערך מקבוצה, יש להשתמש בשיטה Array.from() או בפיזור תחביר:

const mySet = new Set([ 1, 2, 3 ]);
const myArray = Array.from( mySet );

myArray;
> Array(3) [ 1, 2, 3 ]

[ ...mySet ];
> Array(3) [ 1, 2, 3 ]

WeakSet

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

כדי ליצור WeakSet, משתמשים ב-constructor של WeakSet():

const myWeakSet = new WeakSet();

myWeakSet;
> WeakSet []

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

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

בדיקת ההבנה

בהינתן הפרטים הבאים:

        const myMap = new Map([ [ "myKey", "My string" ] ]);
        myMap.set( "myKey", 100 );
      

מה myMap מחזיר?

"My string"
undefined
100