В 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, чтобы получать больше обновлений.
Также, пожалуйста, не забывайте поддерживать социальную дистанцию, чтобы предотвратить распространение вируса, и регулярно мойте руки. Оставайтесь в безопасности и оставайтесь дома.