ES017 – איטרציה של אובייקטים ו-getOwnPropertyDescriptors

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

אובייקטים תמיד היו בעיתיים לאיטרציה בג'אווהסקריפט. בעיקר בגלל הפרוטוטייפ שמסבך מאוד את כל הסיפור של האיטרציה וגם בגלל שאין ממש מתודות טובות לעשות איטרציה באובייקטים. ES017 מנסה להקל על העניין עם entries – מתודה שמחזירה לנו את כל הערכים של האובייקט באופן מסודר כמערך. ונקראת כמתודה של Object. הנה הדוגמה:


let myObj=  {one: 1, two: 2, someProperty: 'Some Value'};

console.log( Object.entries(myObj) ) //[ ["one":, 1], ["two":, 2], ["someProperty":, "Some Value"] ]

כפי שאנו רואים, יש לי אובייקט מסוים ואני פשוט מחלץ את כל ה-key value שלו למערך באופן מסודר באמצעות קריאה ל-Object.entries. עד כמה שזה נשמע מצחיק, לא היתה דרך טובה לעשות זאת עד עכשיו. שימו לב שהתכונות המתקבלות הן התכונות של האובייקט בלבד ולא תכונות שמגיעות דרך הפרוטוטייפ. שזה מעולה לאיטרציות עם for of. הנה הדוגמה:


let myObj=  {one: 1, two: 2, someProperty: 'Some Value'};

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

//"one : 1"
//"two : 2"
//"someProperty : Some Value"

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

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


let myObj=  {one: 1, two: 2, someProperty: 'Some Value'};

console.log( Object.values(myObj) ) //[1, 2, "Some Value"] ]

for (let k of Object.values(myObj)) {
  console.log(k);
}

//1
//2
//"Some Value"

ולמי שרוצה להשתעשע – הנה ה-codepen:

See the Pen ES2017 entries by Ran Bar-Zik (@barzik) on CodePen.

getOwnPropertyDescriptors

פיצ'ר נוסף שיש ל-Object הוא getOwnPropertyDescriptors. הוא די פשוט ומביא את ה-descriptors של האובייקט. למי שלא יודע, אציין בקצרה ש-descriptor הן תכונות של האובייקט. למשל מתודת get או set או תכונות אחרות. כאשר אני משמש ב-getOwnPropertyDescriptors אני יכול לקבל מידע על כל התכונות האלו ואני אדגים:


const obj = {
  somePropery: 123,
  get getSomeProperty() { return this.somePropery },
};
console.log(Object.getOwnPropertyDescriptors(obj));

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


Object
getSomeProperty:Object
configurable:true
enumerable:true
get:getSomeProperty()
set:undefined

somePropery:Object
configurable:true
enumerable:true
value:123
writable:true

משתמשים בזה בעיקר לבצע cloning של אובייקטים מורכבים. למשל, assign לאובייקט מורכב עלול לגרום להתנהגות לא צפויה ולאיבוד מידע על התכונות. בעוד ששימוש מושכל ב-getOwnPropertyDescriptors יכול לפתור את הבעיה. הנה דוגמה:


const obj = {
  somePropery: 123,
  get getSomeProperty() { return this.somePropery },
};

const target1 = {};
Object.assign(target1, obj);

const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(obj));

console.log(Object.getOwnPropertyDescriptors(obj));
console.log('-----------------');
console.log(target1);
console.log('+++++++++++++++++');
console.log(target2);

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

פוסטים נוספים שכדאי לקרוא

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