Symbol и BigInt
↑ 2.1 JavaScript: продвинутый · ← Предыдущая · → Следующая
Зачем это на собесе
Редкие типы, но вопросы «зачем Symbol» и «как хранить большие числа» встречаются.
Объяснение
Symbol — уникальный неизменяемый идентификатор.
const id = Symbol("id");
const user = { name: "A", [id]: 1 }; // ключ-символ: не виден в Object.keys/JSON
Symbol("x") === Symbol("x"); // false
Symbol.for("app.key") === Symbol.for("app.key"); // true: глобальный реестрПрименения: «скрытые» свойства без конфликтов имён, метки, метапрограммирование через well-known symbols:
| Символ | Назначение |
|---|---|
Symbol.iterator | делает объект итерируемым (for...of, spread) |
Symbol.asyncIterator | асинхронная итерация |
Symbol.toPrimitive | преобразование в примитив |
Symbol.toStringTag | Object.prototype.toString |
Symbol.hasInstance | поведение instanceof |
BigInt — целые произвольной точности (суффикс n).
const big = 2n ** 64n; // 18446744073709551616n
9007199254740993n + 1n; // точно, в отличие от Number
BigInt(123); Number(5n); typeof 1n; // "bigint"
1n + 1; // TypeError: смешивать с Number нельзя
5n / 2n; // 2n (целочисленное деление)Применения: идентификаторы (Snowflake, id > 2⁵³), криптография, деньги в минимальных единицах.
Нюансы и подводные камни
JSON.stringifyне поддерживает BigInt (бросает ошибку) — сериализуйте вручную.Math.*не работает с BigInt.- Символ-ключи не попадают в
for...in,Object.keys, JSON (используйтеObject.getOwnPropertySymbols). - Сравнение
1n == 1—true,1n === 1—false. - Идентификаторы, приходящие с сервера как числа > 2⁵³, теряют точность — передавайте строкой.
Практика
- Сделайте объект итерируемым через
Symbol.iterator. - Сохраните id заказа > 2⁵³ без потери точности.
- Реализуйте «приватное» свойство на символе.
Вопросы с ответами
Зачем нужен Symbol?
Создавать уникальные ключи без коллизий и настраивать поведение языка (well-known symbols).
Когда нужен BigInt?
Для целых, превышающих безопасный диапазон
Number(2⁵³−1).