Символы впервые появились в JavaScript в ES6. Давайте посмотрим, что они из себя представляют, как их создавать и как вы можете их использовать (или увидеть, как их использовать).
Символы - это новый примитивный тип данных
Вы правильно прочитали - ES6 представил в JavaScript целый новый примитивный тип данных. Что отличает символы от примитивных типов данных до ES6 (string, number, boolean, null, undefined), так это их уникальность - каждое значение символа гарантированно уникально.
Давайте посмотрим, как создать значение типа symbol:
const dug = Symbol(); dug; // Symbol()
Все просто, правда? Мы объявили константу и присвоили ей возвращаемое значение функции. JavaScript предоставляет встроенную функцию Symbol()
, которая просто возвращает новое значение типа symbol
.
Если мы хотим, мы можем передать необязательное описание для нашего символа. Описание не имеет ничего общего со значением самого символа. Добавление описания выглядит так:
const describeMe = Symbol('description'); describeMe; // Symbol(description)
Еще раз обратите внимание, что в значении символа, хранящемся в describeMe
, нет ничего особенного - наше описание отображается только для целей отладки и не влияет на само значение символа.
Символы уникальны
Здесь следует отметить одну важную вещь: значения символов, которые мы только что сохранили, полностью уникальны. Попробуйте ввести эти операторы в свою консоль, чтобы убедиться в этом:
const dug = Symbol(); dug === Symbol(); // false Symbol() === Symbol(); // false dug === dug; // true
Итак - как мы можем использовать эти уникальные значения? Одно из основных применений символов может заключаться в представлении абстрактных понятий, таких как цвета. До ES6 мы могли сохранить концепцию цвета красный в виде строки, например:
const colourRed = 'red';
Однако довольно легко создать строковые значения, точно эквивалентные colourRed
, которые на самом деле не то же самое, что красный цвет:
const colourRed = 'red'; const siteName = 'reddit'; const shortSiteName = siteName.slice(0,3); shortSiteName; // "red" colourRed === shortSiteName; // true
Используя уникальность символов, мы можем избавиться от этой неоднозначности:
const colourRed = Symbol(); const siteName = 'reddit'; const shortSiteName = siteName.slice(0,3); shortSiteName; // "red" colourRed === shortSiteName; // false
(См. Отличный пример Изучение ES6 доктора Акселя Раушмайера.)
Символы могут использоваться как ключи на объекте
Чаще всего символы используются в качестве ключей объекта. Поскольку символы уникальны, мы можем добавить к объекту столько свойств, сколько захотим, не беспокоясь о конфликте ключей. Более того, поскольку значения символов не наблюдаются напрямую (все они просто возвращают Symbol()
в консоли), они обладают анонимизирующим эффектом при использовании в качестве ключей.
Для иллюстрации давайте создадим объект с несколькими свойствами:
const abby = {}; abby['legs'] = 4; abby['ears'] = 2; abby['nose'] = 1;
Затем мы создадим некоторые значения символов:
const hasFleas = Symbol(); const smellsBad = Symbol();
Наконец, давайте воспользуемся этими значениями символов для хранения дополнительных данных о нашем объекте:
abby[hasFleas] = false; abby[smellsBad] = true;
Давайте посмотрим, как наш объект оценивается в консоли:
abby; // Returns the following - // // ears: 1 // legs: 4 // nose: 1 // Symbol(): false // Symbol(): true
Обратите внимание, что наша информация о блохах и запахе Эбби (собаки) читаема, но ключи, идентифицирующие эту информацию, анонимны. С первого взгляда мы действительно не можем сказать, какое свойство принадлежит к какому.
Однако в лучшем случае это обеспечивает небольшую неясность - это не практики, достаточной для защиты личных данных.
Символы могут хранить метаданные об объектах
Еще одна интересная вещь происходит, когда мы используем символы в качестве ключей к объекту - свойства с символьными ключами пропускаются при итерации. Например, если мы перебираем наш объект abby
, происходит следующее:
for (prop in abby) { console.log(prop, abby[prop]); } // Output // // legs 4 // ears 2 // nose 1
Как видите, символы дают нам возможность хранить дополнительную информацию - метаданные - об объектах, сохраняя при этом нашу способность взаимодействовать с ними привычными способами. Довольно круто!
Вот оно что
Теперь мы на одной волне! Помните эти ключевые выводы:
- Символы - это новый примитивный тип данных
- Значения символов уникальны (в большинстве случаев - но это уже история другого дня: см. методы глобального реестра символов)
- Значения символов могут использоваться в качестве ключей объекта (вместо строковых значений) и никогда не будут конфликтовать с уже существующими ключами.
- Поскольку символьные ключи пропускаются при итерации по объекту, символы позволяют нам хранить дополнительные метаданные об объектах.
Вы используете символы в своем коде? Дайте мне знать в комментариях или найдите меня в Twitter!