Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке Symbol?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`Symbol`** - це унікальне і незмінне значення, яке можна використовувати як ключ властивості об'єкта. **Ключове:** кожен `Symbol` унікальний, навіть якщо в нього однаковий опис, і символьні ключі не беруть участі у `for...in` та `Object.keys()`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке `Symbol` > `Symbol` - це **унікальне і незмінне значення**, > яке можна використовувати як **ключ властивості об'єкта**. Кожен `Symbol` - **унікальний**, навіть якщо в нього однаковий опис. ## Приклад: ```javascript const id1 = Symbol('id'); const id2 = Symbol('id'); console.log(id1 === id2); // false ``` Попри однаковий опис `'id'`, символи не рівні. Кожен `Symbol` - це унікальний ідентифікатор. ## Навіщо потрібен `Symbol` До появи символів ключі властивостей об'єктів були тільки: - рядками (`'name'`, `'age'`); Іноді потрібно **додати в об'єкт "приховану" властивість**, щоб вона **не заважала** решті коду (наприклад, бібліотекам). Ось тут і допомагає `Symbol`. ## Приклад: "прихована" властивість ```javascript const id = Symbol('id'); const user = { name: 'Alex', [id]: 123, // символ як ключ }; console.log(user); // { name: 'Alex', [Symbol(id)]: 123 } console.log(user[id]); // 123 console.log(Object.keys(user)); // ['name'] - символ не видно ``` `Symbol`-ключі **не беруть участі** у `for...in`, `Object.keys()`, і не заважають іншим властивостям. Це зручно для **внутрішніх даних** або **"приватних" властивостей**. ## Символ як ключ - приклад ```javascript const TOKEN = Symbol('token'); const session = { user: 'Tim', [TOKEN]: 'secret-token-123', }; console.log(session.user); // Tim console.log(session[TOKEN]); // secret-token-123 console.log(Object.keys(session)); // ['user'] ``` Тобто властивість `[TOKEN]` **є**, але вона "невидима" для більшості операцій. ## Отримання всіх символів об'єкта Щоб отримати символьні властивості: ```javascript const symbols = Object.getOwnPropertySymbols(session); console.log(symbols); // [Symbol(token)] console.log(session[symbols[0]]); // secret-token-123 ``` ## Символи не перетворюються на рядки ```javascript const sym = Symbol('id'); console.log('Мій символ: ' + sym); // TypeError ``` Щоб вивести символ як рядок: ```javascript console.log(sym.toString()); // Symbol(id) ``` ## Глобальні символи (`Symbol.for`) Іноді потрібно, щоб один і той самий `Symbol` використовувався **в різних частинах програми**. Для цього є глобальний реєстр символів: ```javascript const a = Symbol.for('shared'); const b = Symbol.for('shared'); console.log(a === b); // true ``` `Symbol.for(key)` створює (або повертає вже наявний) глобальний символ. Його можна отримати за ім'ям через `Symbol.keyFor()`: ```javascript console.log(Symbol.keyFor(a)); // 'shared' ``` ## Системні символи (well-known symbols) JS визначає декілька **вбудованих символів**, які дозволяють перевизначати поведінку об'єктів. Наприклад: | Символ | Для чого використовується | |---|---| | `Symbol.iterator` | Дозволяє об'єкту бути ітерованим (`for...of`) | | `Symbol.toPrimitive` | Керує перетворенням об'єкта в примітив | | `Symbol.toStringTag` | Визначає ім'я для `Object.prototype.toString` | | `Symbol.hasInstance` | Визначає поведінку оператора `instanceof` | | `Symbol.species` | Контролює створення підкласів | | `Symbol.asyncIterator` | Для асинхронних ітераторів | ### Приклад `Symbol.iterator` ```javascript const numbers = { data: [1, 2, 3], [Symbol.iterator]() { let i = 0; const arr = this.data; return { next() { return i < arr.length ? { value: arr[i++], done: false } : { done: true }; } }; } }; for (const n of numbers) { console.log(n); // 1, 2, 3 } ``` Завдяки `Symbol.iterator`, об'єкт став "ітерованим". ## Порівняння `Symbol` з іншими типами | Тип | Може бути ключем об'єкта | Унікальність | Бере участь у `for...in` | |---|---|---|---| | `string` | Так | Ні | Так | | `number` | Ні (перетворюється на рядок) | Ні | - | | `Symbol` | Так | Так | Ні | ## Застосування на практиці Використовуй `Symbol`, коли: - потрібно **створити унікальний ідентифікатор**, який не перетнеться з іншими властивостями; - потрібно додати **"приватну" властивість** в об'єкт або клас; - потрібно **налаштувати поведінку об'єктів**, використовуючи системні символи (`Symbol.iterator`, `Symbol.toPrimitive` тощо). ## Коротке резюме | Що | Опис | |---|---| | **Тип** | Примітивний (`symbol`) | | **Головна особливість** | Унікальність | | **Створення** | `Symbol('опис')` | | **Ключі об'єктів** | Можна використовувати як ключ (унікальний і прихований) | | **Глобальні символи** | `Symbol.for()` / `Symbol.keyFor()` | | **Системні символи** | Дозволяють перевизначати поведінку JS |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.