Это короткая, но достаточно полезная статья для продолжающих разработчиков о итераторах в Javascript.  Прежде чем узнаем за итераторы в js, вспомним о том, что такое Symbol: Существуют системные символы, такие как Symbol.iterator , Symbol.toPrimitive и другие. Системные символы используются самим языком, но мы также можем применять их, чтобы изменять дефолтное поведение некоторых объектов. Символы являются частью спецификации es6, поэтому не поддерживаются в ie, совсем (caniuse). В основном этот символ используется языком в цикле for…of при переборе свойств объекта. Так же его можно использовать напрямую со встроенными типами данных: Данный пример со строкой работает, так как у String.prototype имеется свой итератор (спека). Список итерируемых типов в js: String, Array, TypedArray, Map, Set. 
Кроме цикла, javascript использует Symbol.iterator в следующих конструкциях: spread operator, yield, destructuring assignment. При вызове [Symbol.iterator]() возвращается интерфейс итератора, который выглядит так: Методы .next(), .return(), .throw() подготавливают (дальше посмотрим как) и возвращают объект вида: Методы .return() и .throw() используются, например, при преждевременном окончании итерации. Подбробнее о них можно почитать в спеке ecmascript. В качестве примера создадим свою структуру, которую можно проитерировать с помощью for…of и так же посмотрим на применение Symbol.iterator с упомянутыми выше конструкциями языка. Представим что у нас есть маршрут, проложенный через несколько станций, и мы хотим пройти по маршруту и что-то сделать с каждой станцией, например, вывести в консоли.  Создадим класс Route: Как вы можете заметить, наш Route реализует метод Symbol.iterator, таким образом Route является итерируемой сущностью (спека), это означает мы можем пройтись по нему используя for…of (после того как посмотрим реализацию RouteIterator). Метод [Symbol.iterator]() будет вызван столько раз, сколько обращений к нему было. То есть, если несколько циклов друг за другом пытаются пройтись по route, то на каждый цикл будет вызван [Symbol.iterator](), поэтому для каждого вызова мы создаем новый экземпляр RouteIterator. Теперь познакомимся с самим RouteIterator. Это класс реализующий интерфейс итератора для Route сущности. Посмотрим на него: В данном классе мы имеем доступ до итерируемой коллекции (свойство route), так же nextIdx - это указатель на следующее значение в нашей коллекции. Метод next() первым делом проверяет не завершился ли маршрут, и если завершился  -  возвращает что итерации завершены. Иначе мы берем следующее значение в коллекции route, говорим, что итерации не завершены, перемещаем указатель и возвращаем результат.  Теперь мы можем пройтись по коллекции route через for…of: Такой код выведет список станций, который мы передали в Route. Теперь пройдемся по станциям используя функции генераторы: Symbol.iterator используется при деструктуризации: и со spread оператором: Создали свой класс, сделали его итерируемым и использовали с конструкциями javascript'a. Спасибо за внимание =). Невозможно полностью освоить новый материал только одной статьей, поэтому вот несколько дополнительных:
Про паттерн итератор из книги Рефакторинг Гуру
Про Symbol из книги Ильи Кантора и на MDN Frontend Developer