סמל

Browser Support

  • Chrome: 38.
  • Edge: 12.
  • Firefox: 36.
  • Safari: 9.

Source

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

String() === String()
> true

String( "My string." ) === String( "My string." );
> true

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

Symbol() === Symbol()
> false

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

const mySymbol = Symbol( "Desc" );

const myObject = {};
myObject[mySymbol] = "propSymbol";

myObject
> Object { Symbol("Desc"): "propSymbol" }

יש שלושה סוגים של סמלים:

  • סמלים שנוצרו באמצעות Symbol()
  • סמלים משותפים שמוגדרים ומאוחזרים מרשם סמלים גלובלי באמצעות Symbol.for()
  • 'סמלים מוכרים' מוגדרים כמאפיינים סטטיים באובייקט Symbol. הסמלים האלה מכילים שיטות פנימיות שאי אפשר להחליף בטעות.

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

Symbol( "My symbol." ) === Symbol( "My symbol." );
> false

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

let mySymbol = Symbol( "My symbol." );

mySymbol.description
> "My symbol."

אבל אי אפשר ליצור סמל באמצעות מילת המפתח new:

let mySymbol = new Symbol();

> Uncaught TypeError: Symbol is not a constructor

אי אפשר למנות סמלים, כלומר אי אפשר להשתמש במאפיינים סמליים כשמשתמשים בשיטות רגילות כדי לבצע איטרציה עליהם. השיטה getOwnPropertySymbols() מאפשרת גישה למאפייני הסמל של אובייקט.

סמלים משותפים

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

let sharedSymbol = Symbol.for( "My key." );

sharedSymbol === Symbol.for( "My key." )
> true

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

Symbol( "String" ) === Symbol( "String" );
> false

Symbol( "String" ) === Symbol.for( "String" );
> false

Symbol.for( "String" ) === Symbol.for( "String" );
> true

כדי לאחזר את המפתח של כל סמל מרשם הסמלים, משתמשים ב-Symbol.keyFor():

let mySymbol = Symbol.for( "Key." );

Symbol.keyFor( mySymbol ) ;
> "Key."

סמלים 'מוכרים'

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

Symbol;
> function Symbol()
    asyncIterator: Symbol(Symbol.asyncIterator)
    for: function for()
    hasInstance: Symbol("Symbol.hasInstance")
    isConcatSpreadable: Symbol("Symbol.isConcatSpreadable")
    iterator: Symbol(Symbol.iterator)
    keyFor: function keyFor()
    length: 0
    match: Symbol("Symbol.match")
    matchAll: Symbol("Symbol.matchAll")
    name: "Symbol"
    prototype: Object {  }
    replace: Symbol("Symbol.replace")
    search: Symbol("Symbol.search")
    species: Symbol("Symbol.species")
    split: Symbol("Symbol.split")
    toPrimitive: Symbol("Symbol.toPrimitive")
    toStringTag: Symbol("Symbol.toStringTag")
    unscopables: Symbol("Symbol.unscopables")
    <prototype>: function ()

מאחר שסמלים הם תכונה ספציפית ל-ES6, הערכים הסמלים האלה מיועדים לשמש כ'נקודות הרחבה' למפתחים שמשנים את ההתנהגות של JavaScript בלי ליצור בעיות בתאימות לאחור.

לעיתים קרובות, ערכים של סמלים מוכרים מופיעים בסגנון מיוחד עם קידומת @@ או עטופים ב-% כדי להבדיל בין המפתחות שלהם לבין האב טיפוס שלהם שאפשר לשנות. לדוגמה, @@match (או %match%) הוא הפניה ל-Symbol.match הבלתי משתנה, ולא ל-String.prototype.match.

בדיקת ההבנה

אפשר להשתמש ב-new כדי ליצור סמל?

כן
לא

אילו מהסמלים הבאים מתארים סמלים 'ידועים'?

סמלים שבהם אתם משתמשים לעיתים קרובות
מאפיינים סטטיים של אובייקט Symbol
מפתחות ייחודיים של מאפיינים לגישה לשיטות המובנות של JavaScript ולשינוי שלהן