Symbol у JS
Що таке Symbol
Symbol- це примітивний тип даних (введений в ES6), що представляє унікальне і незмінюване значення.
Створюється через функцію:
const id = Symbol();Кожен виклик Symbol() створює нове унікальне значення, навіть якщо описи збігаються.
Приклад
const id1 = Symbol('user');
const id2 = Symbol('user');
console.log(id1 === id2); // falseХоча обидва символи мають однаковий опис
'user', вони різні. КоженSymbol()унікальний.
Навіщо потрібен Symbol
Символи найчастіше використовують як унікальні ключі властивостей об'єкта, щоб уникнути конфліктів імен.
Приклад: звичайні ключі можуть конфліктувати
const user = { name: 'Oleh' };
user.id = 1;
user.id = 2; // перезаписалиА от якщо використовувати Symbol:
const ID = Symbol('id');
const user = {
name: 'Oleh',
[ID]: 1
};
console.log(user[ID]); // 1Тепер властивість [ID]:
- унікальна;
- не видно при звичайному переборі властивостей.
Символи не беруть участі у звичайному переборі
for (let key in user) {
console.log(key);
}
// → "name"console.log(Object.keys(user)); // ["name"]Символ не з'являється у
for...in,Object.keys()іJSON.stringify().
Але його можна отримати:
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
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
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Символ дозволяє контролювати, як об'єкт перетворюється на число або рядок.
Символи можна зберігати в "реєстрі"
Іноді потрібно, щоб символ з однаковим ім'ям був тим самим: для цього є глобальний реєстр символів.
const id1 = Symbol.for('user');
const id2 = Symbol.for('user');
console.log(id1 === id2); // true
Symbol.for(key)шукає символ у глобальному реєстрі. Якщо не знайдено, створює новий і зберігає його під цим ключем.
Отримати опис можна так:
Symbol.keyFor(id1); // 'user'Символи - безпечні "приховані" ключі
Ідеально підходять для:
- створення приватних властивостей у бібліотеках або класах;
- розширення об'єктів без ризику пошкодити чужі дані;
- метаданих (наприклад, у фреймворках або ORM).
Приклад використання в класі
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.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.