Skip to main content

Symbol у JS

Що таке Symbol

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

Створюється через функцію:

javascript
const id = Symbol();

Кожен виклик Symbol() створює нове унікальне значення, навіть якщо описи збігаються.


Приклад

javascript
const id1 = Symbol('user'); const id2 = Symbol('user'); console.log(id1 === id2); // false

Хоча обидва символи мають однаковий опис 'user', вони різні. Кожен Symbol() унікальний.


Навіщо потрібен Symbol

Символи найчастіше використовують як унікальні ключі властивостей об'єкта, щоб уникнути конфліктів імен.


Приклад: звичайні ключі можуть конфліктувати

javascript
const user = { name: 'Oleh' }; user.id = 1; user.id = 2; // перезаписали

А от якщо використовувати Symbol:

javascript
const ID = Symbol('id'); const user = { name: 'Oleh', [ID]: 1 }; console.log(user[ID]); // 1

Тепер властивість [ID]:

  • унікальна;
  • не видно при звичайному переборі властивостей.

Символи не беруть участі у звичайному переборі

javascript
for (let key in user) { console.log(key); } // → "name"
javascript
console.log(Object.keys(user)); // ["name"]

Символ не з'являється у for...in, Object.keys() і JSON.stringify().

Але його можна отримати:

javascript
console.log(Object.getOwnPropertySymbols(user)); // [Symbol(id)]

Символи часто використовуються "всередині" мови

JavaScript має вбудовані (well-known symbols): спеціальні символи, які дозволяють змінювати поведінку вбудованих операцій.


Приклади вбудованих символів:

СимволВикористовується для
Symbol.iteratorробить об'єкт ітерованим (for...of)
Symbol.toPrimitiveналаштовує перетворення до примітиву
Symbol.toStringTagзадає рядок, що повертає Object.prototype.toString
Symbol.hasInstanceперевизначає поведінку instanceof
Symbol.asyncIteratorдозволяє використовувати for await...of

Приклад: Symbol.iterator

javascript
const arr = [1, 2, 3]; const iterator = arr[Symbol.iterator](); console.log(iterator.next()); // { value: 1, done: false }

Символ Symbol.iterator робить масив "ітерованим": саме це дозволяє працювати з for...of і spread (...arr).


Приклад: Symbol.toPrimitive

javascript
const user = { name: 'Oleh', age: 25, [Symbol.toPrimitive](hint) { return hint === 'string' ? this.name : this.age; } }; console.log(String(user)); // "Oleh" console.log(+user); // 25

Символ дозволяє контролювати, як об'єкт перетворюється на число або рядок.


Символи можна зберігати в "реєстрі"

Іноді потрібно, щоб символ з однаковим ім'ям був тим самим: для цього є глобальний реєстр символів.

javascript
const id1 = Symbol.for('user'); const id2 = Symbol.for('user'); console.log(id1 === id2); // true

Symbol.for(key) шукає символ у глобальному реєстрі. Якщо не знайдено, створює новий і зберігає його під цим ключем.

Отримати опис можна так:

javascript
Symbol.keyFor(id1); // 'user'

Символи - безпечні "приховані" ключі

Ідеально підходять для:

  • створення приватних властивостей у бібліотеках або класах;
  • розширення об'єктів без ризику пошкодити чужі дані;
  • метаданих (наприклад, у фреймворках або ORM).

Приклад використання в класі

javascript
const _id = Symbol('id'); class User { constructor(name) { this.name = name; this[_id] = Math.random(); } } const user = new User('Oleh'); console.log(user); // { name: 'Oleh', [Symbol(id)]: 0.123... } console.log(Object.keys(user)); // ["name"]

Символ робить поле _id невидимим при звичайній ітерації і захищає його від випадкового перезаписування.


Підсумок

ВластивістьОпис
ТипПримітив
УнікальністьКожен Symbol() унікальний
Використовується якКлюч для властивостей об'єктів
Не виднопри for...in, Object.keys(), JSON.stringify()
Є глобальний реєстрчерез Symbol.for() і Symbol.keyFor()
Приклади вбудованих символівSymbol.iterator, Symbol.toPrimitive, Symbol.hasInstance та інші

Коротко

  • Symbol() створює унікальне значення, навіть за однакового опису.
  • Використовується для унікальних ключів властивостей.
  • Не бере участі у звичайній ітерації, тому зручний для "приватних" даних.
  • Має вбудовані варіанти (Symbol.iterator, Symbol.toPrimitive та інші), що дозволяють змінювати поведінку стандартних операцій JS.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.