Symbol и BigInt

↑ 2.1 JavaScript: продвинутый · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Редкие типы, но вопросы «зачем 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.toStringTagObject.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⁵³, теряют точность — передавайте строкой.

Практика

  1. Сделайте объект итерируемым через Symbol.iterator.
  2. Сохраните id заказа > 2⁵³ без потери точности.
  3. Реализуйте «приватное» свойство на символе.

Вопросы с ответами

Связанные темы