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 with JavaScript enabled. Enable JavaScript to view data.

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

* Глоссарий: Символьный тип данных (en-US)
* `typeof`
* Типы и структуры данных JavaScript
* "ES6 In Depth: Symbols" on hacks.mozilla.org