Протокол итераций позволяет объектам JavaScript определять и настраивать свое поведение при итерации, то есть указать, какие значения должны быть проитерированы в for...of.
Массивы считаются итерируемыми. Но есть и другие итерируемые объекты (например, строки).
Описание Symbol.iterator
Давайте попробуем создать итерируемый объект.
Например, есть объект, который не является массивом, но подходит для использования в for...of.
Посмотрим на пример объекта диапазона, представляющего интервал чисел:
let range = {
from: 0,
to: 10
};
// We want the for..of to work:
// for(let num of range) ... num=0,1,2,3,4,5,6,7,8,9,10
Чтобы преобразовать диапазон в итерируемый объект, необходимо добавить к объекту метод под названием Symbol.iterator.
Это происходит следующим образом:
- Как только начинается for..of, метод вызывается один раз. Он должен вернуть итератор.
- Затем, for..of может работать с возвращенным объектом.
- Когда for..of ожидает следующее значение, на этом объекте вызывается метод next().
- Его результат должен включать форму {done: Boolean, value: any} .
Весь процесс для диапазона с замечаниями будет выглядеть так:
Самой важной особенностью итерируемых объектов является разделение ответственности. Оно подразумевает, что объект итератора отличается от тех, по которым он итерируется. Их можно объединить, используя диапазон как итератор, чтобы упростить код, как показано ниже:
Основным недостатком в этом случае является то, что невозможно иметь два for..of , которые работают с объектом одновременно.
Могут существовать бесконечные итераторы. Например, вы можете преобразовать диапазон в бесконечный с помощью range.to = Infinity. Есть и другой вариант: вы можете создать итерируемый объект, который генерирует бесконечную последовательность псевдослучайных чисел. Так что ограничений на метод next не накладывается, и он может возвращать больше значений. Следовательно, цикл for..of также станет бесконечным для такого итерируемого объекта. Но его можно остановить с помощью break.
Строки как итерируемые объекты
Наиболее часто используемыми итерируемыми объектами являются строки и массивы.
В случае строки, for..of может проходить по каждому ее символу:
Это будет работать правильно, как показано ниже:
Подобие массива и итерируемые объекты
В этом разделе мы рассмотрим термины "итерируемые объекты" и "подобие массива". Они могут показаться похожими, но это очень разные вещи.
Подобные массивам считаются объектами, содержащими индексы и length. Итерируемые объекты - это объекты, способные реализовать метод Symbol.iterator . Об этом методе было описано выше.
Используя JavaScript, вы часто столкнетесь с объектами, напоминающими массивы, и итерируемыми объектами. Например, строки могут быть и итерируемыми, и похожими на массивы. Напротив, итерируемый объект никогда не может стать похожим на массив, и наоборот.
Рассмотрим пример объекта, который является похожим на массив, но не является итерируемым:
В общем, и итерируемые объекты, и объекты, похожие на массивы, не являются массивами, так как они не содержат методы pop, push и так далее.
Описание Array-form
Array-form - это обобщенный метод, используемый для преобразования итерируемого объекта или объекта, похожего на массив, в настоящий массив. Затем на нем можно вызвать методы массива. Вот пример использования Array-form:
В строке (*), метод Array.from принимает объект, проверяет, является ли он объектом, похожим на массив или итерируемым объектом, затем создает новый массив, копируя в него все элементы. Посмотрим, как это происходит с итерируемым объектом:
Полный синтаксис Array.from выглядит так:
Array.from(obj[, mapFunc, thisArg])
Второй аргумент mapFn - это функция, которая может быть применена к каждому элементу перед его добавлением в массив. Третий аргумент thisArg позволяет установить this для него. Вот пример:
Теперь давайте преобразуем строку в массив символов с помощью Array.from:
В отличие от метода str.split, он зависит от итеративной природы строки.
Он действует так же, как:
Вывод
Итерируемые объекты - это объекты, которые могут использоваться в цикле for..of.
Как правило, они должны реализовывать метод Symbol.iterator. Этот метод, как правило, вызывается автоматически for..of. Но его также можно вызвать напрямую. Объекты, имеющие индексированные свойства, и length считаются похожими на массивы. Они также могут включать другие свойства и методы, но они не являются настоящими массивами. Для их преобразования в массивы можно использовать метод Array.from(obj[, mapFn, thisArg]).
Аргументы mapFn и thisArg позволяют применять функцию к каждому из них.
Время Викторины: Проверьте Свои Навыки!
отовы проверить свои знания? Погрузитесь в наши интерактивные викторины для более глубокого понимания и веселого способа закрепить знания.