> For the complete documentation index, see [llms.txt](https://russ-zhukovsky.gitbook.io/articles-and-questions/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://russ-zhukovsky.gitbook.io/articles-and-questions/es6.md).

# ES6

## Symbol

Это новый примитивный тип данных, как `boolean` или `string`, который нужен для создания уникальных идентификаторов. Для простоты понимания представьте себе функцию которая возвращает всегда уникальный id, только в нашем случае вместо id – символ.

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

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKAXKAgVVK9n4-0KWTK%2F-MKAfYTZc_WXipbe1NeM%2Fimage.png?alt=media\&token=7fbd0702-2720-4c2a-9840-08cbcac35ef9)

**Важно!**&#x20;

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKAXKAgVVK9n4-0KWTK%2F-MKAfG2q9gHbdL0o4cI7%2Fimage.png?alt=media\&token=1e852cd1-82ae-4214-b2b1-9aa4c649b150)

Все другие примитивы могут стать объектами, если объявить их через `new`, а `symbol` не может. Почему так?  Простыми словами — от символа мы хотим получить уникальный идентификатор, то есть сам Символ, а `new` возвращает объект, объект нам не нужен.

&#x20;Существуют «глобальные символы», они доступны во всех частях вашей программы. То есть вы можете создать символ и поместить его в некую базу, это делается с помощью функции `Symbol.for()`

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKAXKAgVVK9n4-0KWTK%2F-MKAfiBMU2LNTZzvTTRS%2Fimage.png?alt=media\&token=a8443a45-2f1f-4134-b596-9a660330615d)

&#x20;Если мы ещё раз вызовем `Symbol.for(“Kanye West”)` он вернёт существующий символ, а не новый. Для глобальных символов, кроме `Symbol.for(key)`, который ищет символ по имени, существует обратный метод: `Symbol.keyFor(sym)`, который, наоборот, принимает глобальный символ и возвращает его имя.

К примеру:

```
// получаем символ по имени
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");

// получаем имя по символу
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
```

Замечание:`Symbol.length`Содержит длину, всегда равную 0 (нулю).

#### Поиск символьных свойств у объектов <a href="#poisk_simvolnykh_svoistv_u_obektov" id="poisk_simvolnykh_svoistv_u_obektov"></a>

Метод [`Object.getOwnPropertySymbols()`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols) возвращает массив символов и позволяет получить символьные свойства конкретного объекта.

#### Зачем нужен Symbol ?

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

Что вы будете делать — создадите новое поле объекта и присвоите ему свои логи. Но тут есть нюанс, если объект используется в большом количестве логики и другие разработчики как-то взаимодействуют с параметрами объекта, то есть шанс, что ваше новое поле где-то сможет сломать цикл, а где-то перезапишет собой другие поля.

Для решение этой проблемы, можно использовать `symbol`

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKAXKAgVVK9n4-0KWTK%2F-MKAgRQGoX-RexJhczYK%2Fimage.png?alt=media\&token=06ad4e52-1b6a-42a0-bb81-9ede36d29c5a)

Как видно, поле, ключом которого является `symbol` , нельзя обнаружить с помощью методов и конструкций вроде `for..in`. Поэтому новое свойство объекта не сломает приложение там, где используется логика похожая на ту, что выше.

## Итераторы

Примеры итерируемого объекта: массив, строка, коллекция DOM-элементов.

Итерируемый объект имеет метод \[Symbol,iterator]\(), который возвращает объект Iterator.\
Iterator содержит метод next(), который возвращает объект, имеющий свойства done, value.

#### Зачем нужен Iterator ?

Когда хочешь перебирать объекты и другие типы данных по своему, итератор это отличный вариант.

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKAXKAgVVK9n4-0KWTK%2F-MKAeGTqKvNx5B0DELEw%2Fimage.png?alt=media\&token=81e26c99-146d-44df-b318-8e6c8d90f6d5)

## Генераторы ( \* yield)

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

**yield** - давать(производить) информацию; уступать или отдавать контроль или ответственность.

Генераторы - позволяют определить алгоритм перебора, написав функцию, которая умеет сама поддерживать собственное состояние (отличие от итераторов).

Генераторы = что мы хотим; Итераторы = как мы хотим это реализовать.

#### Зачем нужен Generator ?

В целом, его используют разные библиотеки как замену `async/await` для работы с асинхронными операциями. Сам `async/await` кстати, это high level абстракция над генераторами. Также популярная [redux-saga](https://github.com/yelouafi/redux-saga) использует генераторы. В остальных случаях их применяют очень редко.

![](https://1064553212-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LzB1eRLbTyixYcoAdRW%2F-MKAXKAgVVK9n4-0KWTK%2F-MKAe1pAIjMw1VbgpRIu%2Fimage.png?alt=media\&token=3070ef16-105c-4935-8f9c-63a7da091cec)

**Yield** как бы говорит — передаём **name** и ставим паузу, пока не произойдёт следующий вызов **next()**.

То есть по сути возвращается объект, свойство **value** которого содержит собственно сгенерированное значение. А свойство **done** указывает, достигли ли мы конца генератора.
