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

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

מפה

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

כדי ליצור מפה, צריך להשתמש במרכיב 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:

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 הוא מפה שמכילה references "חלשות", שצריכות להפנות לאובייקטים או לסמלים שלא נוספו למרשם הסמלים הגלובלי.

כדי ליצור WeakMap, השתמשו בבנאי WeakMap():

const myWeakMap = new WeakMap();

myWeakMap;
> WeakMap(0)

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

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

סיום

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

כדי ליצור סדרה, השתמשו בבנאי 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 של Set. השיטות האלה פועלות על סמך רכיב על סמך הערך של האלמנט עצמו, במקום להתייחס לאינדקס:

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 הוא קבוצה שמכילה רק ערכי garbage-collect, כמו הפניות לאובייקטים או סמלים שלא נוספו למרשם הסמלים הגלובלי.

כדי ליצור WeakSet, השתמש בבנאי WeakSet():

const myWeakSet = new WeakSet();

myWeakSet;
> WeakSet []

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

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

בחינת ההבנה

בהינתן התנאים הבאים:

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

מה הפונקציה myMap מחזירה?

100
"My string"
undefined