[Рекомендации по теме: видеоурок по JavaScript, веб-интерфейс]
Массив— это особый объект, и его отличие от обычных объектов заключается не только в последовательном доступе и хранении элементов. Еще одним важным отличием является то, что массивы являются итерируемыми, то есть вы можете использовать for ... of
для доступа (перебора) ко всем элементам.
Мы можем просто провести небольшой эксперимент:
пусть arr = [1,2,3,4,5]for(let val of arr){ console.log(val)}
результаты выполнения кода:
Приведенный выше код просто использует функцию итерации массива. Когда мы получаем доступ к элементам массива, нам не нужно использовать нижний индекс элемента.
Что произойдет, если мы используем оператор for ... of
для обычного объекта?
пусть объект = { имя: «Сяомин», age:12,}for(let para of obj){ //Код сообщит об ошибке console.log(para)}
Эффект выполнения следующий:
Это доказывает, что между обычными объектами и массивами существует итеративный разрыв. Мы называем объекты с итеративными функциями итерируемыми объектами .
Если мы хотим, чтобы объект был итеративным, мы должны добавить к объекту метод под названием Symbol.iterator
(встроенный Symbol
, который специально делает объекты итерируемыми).
Функции метода включают в себя:
for ... of
для итерации объекта будет вызываться метод Symbol.iterator
, и этот метод должен возвращать итератор (объект с методом next()
).for ... of
будет постоянно вызывать метод итератора next()
для получения следующего элемента.next()
должно соответствовать формату: {done:Boolean,value:any}
. Когда done:true
цикл завершается, в противном случае следующим значением является value
.Итератор: Итератор
— это концепция, заимствованная из таких языков, как
C++
. Принцип работы итератора аналогичен указателю. Он указывает на элемент в коллекции данных. Вы можете получить элемент, на который он указывает, или переместить его. чтобы получить другие элементы. Итераторы аналогичны расширению индексов в массивах. Различные структуры данных, такие как связанные списки (List
), наборы (Set
) и карты (Map
), имеют соответствующие итераторы.Итераторы в
JS
специально созданы для этой операции. Получаемый каждый раз итератор изначально всегда указывает на первый элемент, и итератор имеет только поведениеnext()
до тех пор, пока не будет получен последний элемент набора данных. Мы не можем гибко перемещать позицию итератора, поэтому задача итератора — обходить элементы набора данных в определенном порядке .
Реализуйте итерируемый объект:
let obj = { от: 1, to:5,}obj[Symbol.iterator] = function(){ // Возвращаем итератор return { текущий: this.from, последний: this.to, следующий(){ если (this.current<this.last){ вернуть {сделано: false, значение: this.current++} }еще{ return {done:true}//конец итерации} } }}for(пусть пункт объекта){ console.log(para)}
эффект выполнения кода:
Обратите внимание: хотя вышеуказанные объекты можно повторять, материалом, используемым для итерации, является не объект, а итератор (также объект), возвращаемый Symbol.iterator
.
Приведенный выше код создает встроенную функцию Symbol.iterator()
, которая возвращает объект-итератор. Мы также можем использовать другой способ реализации итераторов: сделать итератором сам объект:
let obj = { от: 1, до: 5, [Символ.итератор](){ это.текущий = это.от; верните это;//Вернем сам объект}, next(){//Добавьте следующий метод к объекту if(this.current<this.to){ вернуть {сделано: false, значение: this.current++} }еще{ вернуть {готово: правда} } }}for(пусть пункт объекта){ console.log(para)}
Эффект выполнения кода такой же, как на рисунке выше.
Хотя при этом код становится более кратким, поскольку новый итерируемый объект не генерируется, мы не можем выполнить два цикла
for ... of
для одновременной итерации одного и того же объекта, но две параллельные итерации выполняются для одного и того же объекта. редкий.
Мы можем обобщить концепцию итерируемых объектов:
так называемые итерируемые объекты — это обычные объекты, у которых есть еще один метод под названием Symbol.iterator
, чем у обычных объектов. Этот метод возвращает итератор.
Альтернативно, объект с Symbol.iterator
и методом next
также является итерируемым объектом.
Массивы и строки являются итерируемыми. Мы можем легко использовать оператор for...of
для перебора символьных элементов в массиве:
let str = '123'for(let c of str){. console.log(c)}
Это также справедливо для суррогатных пар (расширенные символы UTF-16
):
let str = '...'for(let c of str){ console.log(c)}
Эффект выполнения следующий:
предназначены не только for...of
операторов, которые могут использовать итераторы, мы также можем явно вызывать итераторы:
let str = '12345'let itr = str[Symbol.iterator]() while(true){ пусть результат = itr.next() если (result.done) перерыв; console.log(result.value)}
эффект выполнения кода:
Приведенный выше код выполняет операцию обхода символов строки. Вам не кажется, что итерируемые объекты уже не такие загадочные?
Объекты, подобные массиву, и итерируемые объекты очень похожи с точки зрения функций обхода. Оба могут удобно обращаться к внутренним элементам, но между ними все же есть очевидные различия:
iterable
итерируемые объекты: объекты, реализующие Symbol.iterator
;array-like
: имеет числовой индекс и атрибут length
;строка является объектом, который можно повторять, даже если это объект, подобный массиву.
Итерируемые и подобные массиву объекты обычно не являются массивами. Если мы хотим преобразовать итерируемый или подобный массиву объект в массив, нам нужно использовать метод Array.from
.
Используйте Array.from
для преобразования строки в массив:
let str = '123' let arr = Array.from(str)console.log(arr)
Эффект выполнения кода следующий:
Преобразуйте пользовательский объект, похожий на массив, в массив:
let obj = { 0:'0', 1:'1', 2:'2', length:3}let arr = Array.from(obj)console.log(arr)
результат выполнения кода:
Полный синтаксис Array.from
:
Array.from(obj[, mapFunc, thisArg])
Метод mapFunc
будет вызываться для каждого итерируемого или подобного массиву элемента перед созданием массива. Если mapFunc
является методом-членом, вы можете использовать thisArg
чтобы предоставить this
указатель.
Например:
let str = '12345'let arr = Array.from(str,itm=>+itm)console.log(arr)
результат выполнения кода:
Здесь функция сопоставления используется для преобразования массива символов, который должен быть сгенерирован, в числовой массив.
for...of
, называются итерируемыми объектами.Symbol.iterator
на основе обычных объектов.Symbol.iterator
возвращает итератор,next
методnext
метода должно соответствовать формату {done:Boolean,value:nextVal}
. Когда done:true
, итерацияArray.from
может преобразовать массивы классов и
итерируемые объекты в массивы.
[Рекомендации по теме: видеоуроки по JavaScript, веб-интерфейс]
Выше приведено подробное объяснение принципов реализации массивов классов и итерируемых объектов JavaScript. Для получения дополнительной информации обратите внимание на другие соответствующие статьи. сеть исходного кода!