Символ

Примитивный тип, представляющий собой уникальный идентификатор. Используется как имя свойств в объектах.

Время чтения: меньше 5 мин

Кратко

Секция статьи "Кратко"

Символ (Symbol) — примитивный тип, значения которого создаются с помощью вызова функции Symbol. Каждый созданный символ уникален.

Символы могут использоваться в качестве имён свойств в объектах. Символьные свойства могут быть прочитаны только при прямом обращении и не видны при обычных операциях.

Как пишется

Секция статьи "Как пишется"

Создание

Секция статьи "Создание"

Для создания символа нужно вызвать функцию Symbol:

        
          
          const sym = Symbol()const symTwo = Symbol()console.log(sym === symTwo)// false
          const sym = Symbol()
const symTwo = Symbol()

console.log(sym === symTwo)
// false

        
        
          
        
      

При создании символа первым аргументом можно передать его описание. Оно ни на что не влияет и необходимо только для отладки. Даже если описания символов совпадают, JavaScript всё равно создаёт уникальные символы:

        
          
          const sym = Symbol('name')const symTwo = Symbol('name')console.log(sym === symTwo)// false
          const sym = Symbol('name')
const symTwo = Symbol('name')

console.log(sym === symTwo)
// false

        
        
          
        
      

Использование

Секция статьи "Использование"

Символы используются для создания скрытых свойств объектов. В отличие от свойств, ключом которых является строка, символьные свойства может читать только владелец символа. Скрытые свойства не видны при его обходе с помощью for...in:

        
          
          const secondaryId = Symbol()const user = {  'id': 193,  'name': 'Ольга',  [secondaryId]: 'olga-1'}for (const prop in user) {  console.log(prop, user[prop])}// id 193// name Ольгаconsole.log(user[secondaryId])// olga-1
          const secondaryId = Symbol()

const user = {
  'id': 193,
  'name': 'Ольга',
  [secondaryId]: 'olga-1'
}

for (const prop in user) {
  console.log(prop, user[prop])
}
// id 193
// name Ольга

console.log(user[secondaryId])
// olga-1

        
        
          
        
      

Это может пригодиться, когда необходимо добавить свойства объекту, который могут модифицировать другие части программы. Таким образом только вы сможете читать созданное свойство, а гарантия уникальности символов гарантирует и отсутствие конфликтов имён.

Системные символы

Секция статьи "Системные символы"

Символы активно используются внутри самого JavaScript чтобы определять поведение объектов. Такие символы называются «хорошо известными» (well-known symbols).

Самый известный символ Symbol.iterator, который позволяет реализовать обход конструкции с помощью синтаксических конструкций for..of и спред-синтаксиса.

Полный список таких символов доступен в спецификации, но на практике он нужен нечасто.

Глобальный реестр символов

Секция статьи "Глобальный реестр символов"

Созданный символ уникален, но как быть, если он нужен в нескольких местах программы? Для решения этой проблемы существует глобальный реестр символов, он хранит символы по строковым ключам. При обращении по ключу всегда будет возвращаться один и тот же символ.

Работа с реестром символов организована с помощью двух методов:

  • Symbol.for(ключ) — возвращает символ, хранящийся по ключу. Если символа ещё не существует, он создаётся автоматически.
  • Symbol.keyFor(символ) — возвращает строковый ключ, который хранит переданный символ или undefined, если символ не хранится в реестре.
        
          
          const secondaryId = Symbol()const user = {  'id': 193,  'name': 'Ольга',  [secondaryId]: 'olga-1'}console.log(Symbol.keyFor(secondaryId))// undefinedconst newSym = Symbol.for('registryKey')const newestSym = Symbol.for('registryKey')console.log(newSym === newestSym)// trueuser[newSym] = 'hello'console.log(Symbol.keyFor(newSym))// registryKey
          const secondaryId = Symbol()

const user = {
  'id': 193,
  'name': 'Ольга',
  [secondaryId]: 'olga-1'
}

console.log(Symbol.keyFor(secondaryId))
// undefined

const newSym = Symbol.for('registryKey')
const newestSym = Symbol.for('registryKey')
console.log(newSym === newestSym)
// true

user[newSym] = 'hello'
console.log(Symbol.keyFor(newSym))
// registryKey