Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке Symbol і де символи використовують на практиці?

Symbol - примітивний тип для унікальних ідентифікаторів. Кожен виклик Symbol() створює значення, що не дорівнює жодному іншому, навіть з тим самим описом:

const id1 = Symbol('id');
const id2 = Symbol('id');
id1 === id2;   // false

Опис ('id') - лише для налагодження, на унікальність не впливає.

Символи як ключі властивостей - не конфліктують з жодними іншими ключами:

const internal = Symbol('internal');

const user = { name: 'Оля', [internal]: { loadedAt: Date.now() } };

Object.keys(user);        // ['name'] - символьний ключ прихований
JSON.stringify(user);     // '{"name":"Оля"}'
user[internal];           // доступ лише з посиланням на сам символ

Бібліотека може додати службові дані до чужого об'єкта, не ризикуючи зіткнутися з його полями і не потрапляючи в серіалізацію чи for...in. Але символьні ключі не приватні: Object.getOwnPropertySymbols() чи Reflect.ownKeys() їх покажуть.

Глобальний реєстр - Symbol.for(key) повертає той самий символ для того самого ключа в усьому застосунку (навіть між iframe):

Symbol.for('app.cache') === Symbol.for('app.cache');   // true

Найважливіше практичне застосування - вбудовані (well-known) символи. Через них ваші об'єкти підключаються до механізмів мови:

  • Symbol.iterator - об'єкт стає ітерованим (for...of, spread):
class Range {
  constructor(from, to) { this.from = from; this.to = to; }
  *[Symbol.iterator]() {
    for (let n = this.from; n <= this.to; n++) yield n;
  }
}
[...new Range(1, 3)];   // [1, 2, 3]
  • Symbol.asyncIterator - для for await...of;
  • Symbol.toPrimitive - перетворення на число чи рядок;
  • Symbol.toStringTag - що показує Object.prototype.toString ([object Money]);
  • Symbol.hasInstance - поведінка instanceof;
  • Symbol.dispose / Symbol.asyncDispose - для явного керування ресурсами (using).

Ще застосування:

  • значення-«константи», які гарантовано не збігаються з даними: const NOT_FOUND = Symbol('not found') замість null чи -1, які можуть бути реальними значеннями;
  • ключі для provide/inject у Vue - щоб різні бібліотеки не перезаписали одна одній залежності.

Обмеження: символ не перетворюється неявно на рядок (`${sym}` - TypeError), лише явно через String(sym) чи sym.description.

Докладніше в документації: Symbol

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання