Symbol

Сводка

Символ (анг. Symbol) — это уникальный и неизменяемый тип данных, который может быть использован как идентификатор для свойств объектов. Символьный объект (анг. symbol object) — это объект-обёртка (англ. wrapper) для примитивного символьного типа.

Синтаксис

Symbol([описание])

Параметры

описание Необязательный
Необязательный, строка. Описание символа, которое может быть использовано во время отладки, но не для доступа к самому символу.

Описание

Чтобы создать новый символьный примитив, достаточно написать Symbol(), указав по желанию строку в качестве описания этого символа:

var sym1 = Symbol();
var sym2 = Symbol("foo");
var sym3 = Symbol("foo");

Код выше создает три новых символа. Заметьте, что Symbol("foo") не выполняет приведение (англ. coercion) строки "foo" к символу. Это выражение создает каждый раз новый символ:

Symbol("foo") === Symbol("foo"); // false

Код ниже с оператором new бросит исключение TypeError:

var sym = new Symbol(); // TypeError

Это удерживает разработчиков от создания явного объекта-обёртки Symbol вместо нового символьного значения. Создание явных объектов-обёрток для примитивных типов доступно (например, new Boolean, new String, new Number).

Если вам действительно необходимо обернуть символ в объект, вы можете использовать функцию Object():

var sym = Symbol("foo");
typeof sym;     // "symbol" 
var symObj = Object(sym);
typeof symObj;  // "object"

Разделяемые символы в глобальном символьном реестре

Приведенный выше синтаксис, использующий функцию Symbol(), не создаст глобальный символ, который был бы доступен в любом месте вашего кода. Для создания символов, доступных во всех файлах и в окружении (глобальной области), используйте методы Symbol.for() и Symbol.keyFor(), чтобы задать или получить символ из глобального символьного реестра.

Поиск символьных свойств у объектов

Метод Object.getOwnPropertySymbols() возвращает массив символов и позволяет получить символьные свойства конкретного объекта. Следует заметить, что при инициализации объекты не получают символьных свойств, так что этот массив будет пуст, пока вы не зададите ему какое-либо символьное свойство.

Свойства

Symbol.length
Содержит длину, всегда равную 0 (нулю).
Symbol.prototype
Содержит прототип конструктора Symbol.

Известные символы

В добавок к вашим собственным символам, JavaScript имеет несколько встроенных символов, представляющих внутренние механизмы языка, которые не были доступны разработчикам в версиях ECMAScript 5 и более ранних. Эти символы доступны посредством следующих свойств:

Итерационные символы

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

Символы регулярных выражений

Symbol.match
Метод для сопоставления объекта со строкой, также используемый для определения возможности объекта выступать в качестве регулярного выражения. Используется функцией String.prototype.match().
Symbol.replace
Метод, заменяющий совпавшие подстроки в строке. Используется функцией String.prototype.replace().
Symbol.search
Метод, возвращающий индекс вхождения подстроки, соответствующей регулярному выражению. Используется функцией String.prototype.search().
Symbol.split
Метод, разбивающий строку на части в местах, соответствующих регулярному выражению. Используется функцией String.prototype.split()

Другие символы

Symbol.hasInstance
Метод, определяющий, распознает ли конструктор некоторый объект как свой экземпляр. Используется оператором instanceof.
Symbol.isConcatSpreadable
Булево значение, показывающее, должен ли объект быть сведен к плоскому представлению (англ. flatten) в виде массива его элементов функцией Array.prototype.concat().
Symbol.unscopables
Массив строковых имен свойств. Позволяет скрыть свойства от инструкции with (прежде всего для обратной совместимости).
Symbol.species
Метод, определяющий конструктор для порождённых объектов.
Symbol.toPrimitive
Метод, преобразующий объект в примитив (примитивное значение).
Symbol.toStringTag
Строковое значение, используемое в качестве описания объекта по умолчанию. Используется функцией Object.prototype.toString()

Методы

Symbol.for(key)
Ищет существующие символы по заданному ключу и возвращает его, если он найден. В противном случае создается новый символ для данного ключа в глобальном реестре символов.
Symbol.keyFor(sym)
Получает по разделямому символу его ключ из глобального реестра символов.

Прототип Symbol

Все символы наследуют от Symbol.prototype.

Свойства

Symbol.prototype.constructor
Returns the function that created an instance's prototype. This is the Symbol function by default.

Методы

Symbol.prototype.toSource()
Returns a string containing the source of the Symbol object. Overrides the Object.prototype.toSource() method.
Symbol.prototype.toString()
Returns a string of containing the description of the Symbol. Overrides the Object.prototype.toString() method.
Symbol.prototype.valueOf()
Returns the primitive value of the Symbol object. Overrides the Object.prototype.valueOf() method.
Symbol.prototype[@@toPrimitive]
Returns the primitive value of the Symbol object.

Примеры

Использование оператора typeof с символами

Оператор typeof позволяет идентифицировать символ.

typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'

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

Следующее необходимо помнить при преобразовании типа символов.

  • При попытке конвертировать символ в число, будет брошено исключение TypeError (напр., +sym или sym | 0).
  • Результатом нестрогого сравнения, Object(sym) == sym, будет true.
  • Symbol("foo") + "bar" бросает исключение TypeError (невозможно преобразовать символ в строку). Это удерживает разработчика от, к примеру, случайного создания строкого поля у объекта из символа.
  • Более  "безопасный" вызов String(sym) работает с символами как вызов Symbol.prototype.toString(). Заметьте, что в то же время new String(sym) бросит исключение.

Символы и конструкция for...in

Символы не перечисляются при итерации for...in. В дополнение к этому, Object.getOwnPropertyNames() не вернет символьные свойства объекта. Тем не менее, их можно получить с помощью Object.getOwnPropertySymbols().

var obj = {};

obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";

for (var i in obj) {
   console.log(i); // выведет "c" и "d"
}

Символы и JSON.stringify()

JSON.stringify() игнорирует свойства с ключами Symbol:

JSON.stringify({[Symbol("foo")]: "foo"});                 
// '{}'

Подробности см. JSON.stringify().

Объекты-обёртки для Symbol в качестве имен свойств

Когда объект-обёртка символа используется в качестве имени свойства, этот объект сводится к символу, который он оборачивает:

var sym = Symbol("foo");
var obj = {[sym]: 1};
obj[sym];            // 1
obj[Object(sym)];    // снова 1

Спецификации

Спецификация Статус Комментарий
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Symbol' в этой спецификации.
Стандарт Изначальное определение
ECMAScript 2017 Draft (ECMA-262)
Определение 'Symbol' в этой спецификации.
Черновик  

Поддержка браузерами

Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базовая поддержка 38 36 (36) Нет 25 9
Symbol.iterator (@@iterator) 38 36 (36) Нет 25 9
Symbol.unscopables (@@unscopables) 38 48 (48) Нет 25 9
Symbol.match (@@match) ? 40 (40) Нет ? ?
Symbol.species (@@species) ? 41 (41) Нет ? ?
Symbol.toPrimitive (@@toPrimitive) ? 44 (44) Нет ? ?
Symbol.replace (@@replace) ? 48 (48) Нет ? ?
Symbol.search (@@search) ? 48 (48) Нет ? ?
Symbol.split (@@split) ? 48 (48) Нет ? ?
Symbol.isConcatSpreadable (@@isconcatspreadable) ? 48 (48) Нет ? ?
Symbol.hasInstance (@@hasInstance) ? 50 (50) Нет ? ?
Symbol.toStringTag (@@toStringTag) ? 51 (51) Нет ? ?
Возможность Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базовая поддержка ? 38 36.0 (36) Нет 25 9
Symbol.iterator (@@iterator) ? 38 36.0 (36) Нет 25 9
Symbol.unscopables (@@unscopables) ? 38 48.0 (48) Нет 25 9
Symbol.match (@@match) ? ? 40.0 (40) Нет ? ?
Symbol.species (@@species) ? ? 41.0 (41) Нет ? ?
Symbol.toPrimitive (@@toPrimitive) ? ? 44.0 (44) Нет ? ?
Symbol.replace (@@replace) ? ? 48.0 (48) Нет ? ?
Symbol.search (@@search) ? ? 48.0 (48) Нет ? ?
Symbol.split (@@split) ? ? 48.0 (48) Нет ? ?
Symbol.isConcatSpreadable (@@isconcatspreadable) ? ? 48.0 (48) Нет ? ?
Symbol.hasInstance (@@hasInstance) ? ? 50.0 (50) Нет ? ?
Symbol.toStringTag (@@toStringTag) ? ? 51.0 (51) Нет ? ?

См. также

Метки документа и участники

 Внесли вклад в эту страницу: pk.prog, smurf, neutral, schyzoo
 Обновлялась последний раз: pk.prog,