האמת היא ש-Symbol זה פיצ'ר קצת מוזר ב-ECMAScript 6, אני קודם אסביר עליו ואז אני אסביר למה הוא טוב. התווכחתי עם כמה מתכנתים נוספים בנוגע אליו. אני חושב שהשימושים המעשיים שלו מאוד מוגבלים, אם בכלל והם חושבים שיש מצב שנראה את זה. מה שכן, הוא יחסית פשוט אז כדאי לעבור עליו.
באופן עקרוני, Symbol זה סוג פרימיטיבי של מידע ייחודי, מיוחד שאינו חוזר על עצמו ואינו ניתן לשינוי. מייצרים אותו עם Symbol (ללא new כי זה פרימיטיב).
var oneSymbol = Symbol();
var twoSymbol = Symbol();
console.log(oneSymbol === twoSymbol); //false
מה שנכנס לתוך משתנה oneSymbol הוא ה-Symbol. ערך ייחודי לחלוטין שנשמר ברפרנס. אי אפשר לקבוע דבר בנוגע לערך הזה מלבד דבר קיומו. אם אייצר עוד Symbol ואכניס אותו ל-twoSymbol, הוא לא יהיה אותו הדבר ומדובר בשני ערכים שונים לחלוטין.
לשם דיבאגינג בלבד, אני יכול להכניס תיאור ל-symbol, אבל הוא יהיה זמין בקונסול בלבד:
var oneSymbol = Symbol('this is a descriptive description');
console.log(oneSymbol); //Symbol(this is a descriptive description)
ככה זה יראה, אגב:
אם נעשה ל-Symbol typeof, נראה שהוא בסך הכל Symbol:
var oneSymbol = Symbol();
console.log(typeof oneSymbol); //"symbol"
נשאלת השאלה למה צריך את זה, וזו שאלה מצוינת. כאשר ה-Symbol הוא לא גלובלי, השימושים שלו מועטים – בדרך כלל בכל פעם שצריך משהו ייחודי (ולפעמים צריך). יש כאלו שמשתמשים ב-Symbol כדי לסמלץ משתנה פרטי ב-class. הנה דוגמה:
class Something {
constructor(){
var property = Symbol();
this[property] = 'test';
}
}
var instance = new Something();
console.log(instance[property]); //undefined, can only access with access to the Symbol
אבל לדעתי זה משהו שעדיף לא לעשות עם Symbol. הכוח הגדול של Symbol הוא דווקא בצד הגלובלי.
Symbol.for – גלובלי
פה זה כבר מתחיל להיות מעניין. בואו נעבור במהירות על ה-API.
בניגוד ל-Symbol רגיל, עם Symbol.for אני יכול לקבוע 'מפתח' ל-Symbol שהוא יוצר symbol ייחודי למפתח הזה. ואני אדגים:
var oneSymbol = Symbol.for('foo');
var secondSymbol = Symbol.for('foo');
console.log(oneSymbol === secondSymbol); //true
אם יש לי Symbol גלובלי, אני יכול למצוא אותו בקלות עם מתודת forKey:
var oneSymbol = Symbol.for('foo');
console.log(Symbol.keyFor(oneSymbol)); //foo
סבבה, נכון? אבל מה שחזק ממש הוא שה-Symbol שיווצר הוא אותו Symbol על פני חלקים שונים באפליקציה שלי. כלומר אם יש קוד שמייצר Symbol ב-iframe למשל וקוד שמייצר ב-window, זה יהיה אותו Symbol! אני אדגים:
var frame = document.createElement('iframe')
document.body.appendChild(frame)
console.log(Symbol.for('foo') === frame.contentWindow.Symbol.for('foo'))
בקוד הזה אני יוצר iframe ומדביק אותו ל-window שלי. אני יוצר Symbol גם ב-iframe וגם באפליקציה שלי ונראה שהתוצאה תהיה true.
זה מאוד מגניב וגם עלול להיות שימושי אם אני רוצה לחלוק מידע בין iframe ל-window. באופן אישי? הייתי משתמש בזה אך ורק אם אצטרך אי פעם מסמן ייחודי למשהו.
4 תגובות
לדעתי במקום
console.log(instance.property); //undefined, can only access with access to the Symbol
היה צריך להיות
console.log(instance[property]); // prints test
כמו כל משתנה אחר שעל פיו תחפש באובייקט.
אתה צודק כמובן, הדוגמה היתה שגויה… תיקנתי 🙂 תודה!
זה הרבה יותר מורכב ממה שנאמר
שימושי מאוד. תודה!