В ES6 мы познакомились с концепцией Iterables. Итерация по массиву с использованием цикла for-in или for-of для нас не новость.

Все мы хоть раз делали что-то подобное в нашей кодовой базе:

Но что, если вы захотите иметь ту же функцию перебора чего-то, что не является массивом. Как насчет объекта?

Чтобы перебрать его значения, нам, возможно, придется использовать Object.values ​​с картой.

Как насчет того, чтобы не делать values и map, а вместо этого просто полагаться на for-of?. Это именно то, что мы попытаемся охватить с помощью Iterables. Iterable позволит нам использовать значения любого типа структуры данных, используя for-of.

Примечание. Если вы уже знаете, что такое итерируемые объекты, вы можете сразу перейти к разделу «Пользовательские итерации».

Итак, очевидный вопрос: что такое Iterable?

Проще говоря, Iterable - это специальный объект, который должен реализовать метод с ключом Symbol.iterator и возвращает Iterator.

Iterable должен реализовать протокол итераций, который согласно MDN определяется как:

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

Таким образом, любой объект, который хочет быть итерируемым, должен реализовать метод с именем [Symbol.iterator] и вернуть Iterator .

🤔 Что такое Итератор сейчас?

Итератором может быть любой объект javascript, внутри которого есть метод next () и который возвращает объект с двумя ключами - value и done .

Интерфейсы машинописного текста для всего этого будут выглядеть примерно так:

Таким образом, объект становится итератором, когда он реализует метод next () и возвращает объект со следующими ключами:

  • done - логический флаг, указывающий конец итерации.
  • значение - повторяющееся текущее значение.

Таким образом и массив становится повторяемым. Он встроен в язык, поэтому мы этого не видим:

💡Как массивы справляются с этим самостоятельно?

Итак, в случае массивов, если вы когда-либо использовали цикл for-of, тогда for-of внутренне вызывает [Symbol.iterator] , а затем на каждой итерации до тех пор, пока done не станет false, он будет вызывать метод next () метод.

В приведенном выше примере реализация Array будет состоять из чего-то вроде этого:

🕹️ Пользовательские итерации

Теперь, когда мы поняли, что такое Iterables и как их использовать, давайте создадим настраиваемую итерацию, которая будет напоминать функцию range в python .

Для людей, которые не знают, что функция arange делает в Python, вот пример:

Мы хотели бы добиться аналогичной функциональности в Javascript.

Итак, прежде всего давайте создадим rangeIterable.

Он принимает три параметра: начальное значение, конечное значение и счет шага, которое он должен использовать для увеличения предыдущего числа. Он реализует итеративный протокол, поскольку он возвращает объект с методом [Symbol.iterator], который, в свою очередь, возвращает объект с методом next ().

Итак, логика проста: мы начинаем с начального значения и пока это значение не станет меньше стопа, мы продолжаем увеличивать его на счетчик шагов.

Теперь с этим мы можем перебирать значения с помощью функции for-of, даже если наш источник данных rangeIterable не является массивом и не возвращает ничего похожего на массив.

Наконец, чтобы сделать его точно таким же, как функция python range, мы будем использовать Array.from, который может принимать любой итеративный источник и преобразовывать его в массив.

И это все. Теперь я могу использовать эту функцию диапазона где угодно, например, как она работает в Python.

console.log(range(1,4)); // 1,2,3,4
console.log(range(1,10,2); // 1,3,5,7,9
// we can also chain it with other higher order functions
console.log(range(1,4).map(x => x*2); // 2,4,6,8

🍬 Заключение

Я надеюсь, что это поможет нам всем понять, что такое итерируемые объекты и как любой настраиваемый источник данных может предоставлять свои данные, которые могут использоваться объектами for-of или Array.from.

Вы можете следить за мной в Твиттере @ VivekNayyar09, чтобы получать больше обновлений.

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

🔗 Ссылки