Symbol

Сводка

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

Синтаксис

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

Параметры

описание Необязательный

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

Описание

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

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

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

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

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

js
var sym = new Symbol(); // TypeError

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

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

js
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 (en-US)

Содержит прототип конструктора 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 (en-US).

Свойства

{{page('en-US/Web/JavaScript/Reference/Global_Objects/Symbol/prototype','Properties')}}

Методы

{{page('en-US/Web/JavaScript/Reference/Global_Objects/Symbol/prototype','Methods')}}

Примеры

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

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

js
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() (en-US). Заметьте, что в то же время new String(sym) бросит исключение.

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

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

js
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:

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

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

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

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

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

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

Specification
ECMAScript Language Specification
# sec-symbol-objects

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также