W3docs

Тип Symbol в JavaScript

Изучите тип Symbol в JavaScript: создание уникальных значений, использование символов как скрытых ключей объекта, глобальный реестр Symbol.for и Symbol.keyFor, а также встроенные символы.

Введение в символы JavaScript

Символы, появившиеся в ECMAScript 2015 (ES6), — это уникальный и неизменяемый тип данных, который применяется прежде всего для добавления уникальных ключей свойств к объектам. В этом руководстве рассматриваются символы, их практическое применение и то, как они расширяют возможности JavaScript-разработки благодаря уникальным идентификаторам и возможностям метапрограммирования.

Понимание символов

Symbol — это уникальное и неизменяемое примитивное значение, которое может использоваться в качестве ключа свойства object. Каждое значение Symbol, возвращаемое Symbol(), отличается от всех остальных, что гарантирует его уникальность.

Пример: создание и использование символов

javascript— editable

sym1 создаётся без описания, тогда как sym2 и sym3 создаются с одинаковым описанием. Несмотря на одинаковое описание, sym2 и sym3 являются уникальными символами.

Обратите внимание, что в этом примере функция String() используется для преобразования символов в строковый формат для безопасного вывода в лог.

Символы как ключи свойств

Использование символов в качестве ключей свойств позволяет добавлять «скрытые» свойства, которые игнорируются при обычном перечислении. Свойство с символьным ключом пропускается при for...in, Object.keys() и JSON.stringify(). Именно это делает символы полезными для хранения метаданных, которые не должны попадать в сериализованные данные или случайные циклы перебора. Для получения символьных ключей используйте Object.getOwnPropertySymbols() или Reflect.ownKeys() (последний возвращает как строковые, так и символьные ключи). Атрибуты свойства с символьным ключом — writable, enumerable, configurable — по-прежнему можно задавать через Object.defineProperty(), точно так же, как для строкового ключа (см. Флаги и дескрипторы свойств).

Чтобы использовать символ в качестве ключа в литерале объекта, заключите его в квадратные скобки: [id]. Без скобок литерал создаст обычный строковый ключ с именем "id".

Пример: символы пропускаются при перечислении

javascript— editable

Объект user хранит 123 под символьным ключом, к которому можно обратиться только при наличии исходного символа id. Поскольку Object.keys, for...in и JSON.stringify его игнорируют, значение не попадает в сериализованные данные и не появляется в обычных циклах перебора свойств — однако оно не является по-настоящему приватным: с помощью Object.getOwnPropertySymbols его всё равно можно обнаружить.

Совместное использование символов с Symbol.for и Symbol.keyFor

Символы, созданные с помощью Symbol.for, хранятся в глобальном реестре символов и доступны из любого места в коде, обеспечивая согласованные ссылки через методы Symbol.for и Symbol.keyFor.

Пример: совместное использование символов

javascript— editable

Ключевое отличие от Symbol(): Symbol.for(key) ведёт глобальную таблицу с доступом из любого контекста, индексированную по строке. При двукратном вызове с одним и тем же ключом возвращается тот же символ — даже из разных файлов или модулей. Это удобно, когда независимые части приложения должны согласованно использовать один символ, не импортируя его друг у друга. Symbol.keyFor выполняет обратный поиск, но только для символов из реестра; для обычного Symbol() он возвращает undefined.

Практические примеры

Рассмотрим несколько практических примеров того, как символы можно применять в реальных сценариях.

1. Управление доступом к свойствам объекта

Символы особенно полезны, когда нужно контролировать доступ к определённым свойствам объекта, исключая их случайное изменение или чтение через стандартные методы доступа к свойствам.

Пример: приватные члены в классах

При создании классов в JavaScript может потребоваться иметь приватные свойства, к которым нельзя обращаться напрямую за пределами методов класса. Символы позволяют реализовать подобие приватности.

javascript— editable

2. Предотвращение коллизий имён свойств

При работе с примесями (mixins) или расширении объектов, где вы не контролируете все имена свойств, символы помогают избежать коллизий имён свойств.

Пример: безопасные примеси

При расширении объекта дополнительной функциональностью из нескольких источников символы гарантируют отсутствие коллизий ключей, которые могли бы перезаписать существующие свойства.

javascript— editable

3. Метапрограммирование

Символы являются неотъемлемой частью возможностей метапрограммирования JavaScript. Ряд широко известных символов используется для изменения или настройки поведения экземпляров объектов. Помимо Symbol.iterator, такие символы как Symbol.toStringTag (настраивает вывод Object.prototype.toString) и Symbol.hasInstance (настраивает поведение instanceof) обеспечивают глубокую интеграцию с языком.

Пример: пользовательские итераторы

С помощью символов можно определять пользовательское поведение итерации для объектов, используя свойство Symbol.iterator.

javascript— editable

4. Символы для отладки

Символы также могут быть полезны при отладке: к объектам можно прикреплять мета-информацию, не влияя на их операционное поведение.

Пример: добавление отладочной информации

javascript— editable

Эти примеры показывают, как символы можно применять в практических сценариях для более безопасного управления свойствами объектов, расширения функциональности без конфликтов и реализации продвинутых техник программирования в JavaScript.

Встроенные символы

JavaScript предопределяет набор «встроенных» символов непосредственно на объекте Symbol — например Symbol.iterator, Symbol.toPrimitive, Symbol.toStringTag и Symbol.hasInstance. Они не находятся в глобальном реестре; это фиксированные точки расширения, к которым язык обращается в определённые моменты. Реализовав один из них в своём объекте, вы можете настроить встроенное поведение.

Настройка преобразования примитивов с Symbol.toPrimitive

Когда объект используется там, где ожидается примитив — строковая интерполяция, арифметика, сравнение — JavaScript вызывает метод Symbol.toPrimitive объекта (если он определён), передавая подсказку hint со значением "string", "number" или "default". Это позволяет управлять всеми преобразованиями в одном месте, не переопределяя toString и valueOf по отдельности. Полный набор правил описан в разделе Преобразование объектов в примитивы.

javascript— editable

Поскольку логика преобразования скрыта за символьным ключом, она никогда не конфликтует с собственными свойствами данных и не появляется в JSON.stringify.

Заключение

Символы в JavaScript предоставляют надёжный способ работы с уникальными идентификаторами и позволяют разработчикам управлять свойствами объектов с высокой степенью контроля и приватности. Использование символов гарантирует корректное взаимодействие со свойствами и исключает непредвиденные побочные эффекты.

Практика

Практика
Каковы некоторые характеристики типа Symbol в JavaScript?
Каковы некоторые характеристики типа Symbol в JavaScript?
Was this page helpful?