Один для перечислимых, один для итераций ... как использовать каждый?
Зацикливание прошло долгий путь. Начиная с while
циклов и переходя к ванильным for
циклам, ни один из них не перебирает фактическую структуру данных. Скорее, они повторяют последовательность, которая отражает идентификаторы пользователя.
let nums = [1,2,3,4,5]; for(let i=0; i < nums.length; i++) { console.log(nums[i]); }
Переменная i
на самом деле не является частью nums
, но аналогична индексам nums
.
В современном JavaScript есть более эффективные способы перебора данных - в частности, циклы for...in
и for...of
. Узнайте разницу между ними, а также основные принципы, которые помогут нам в выборе каждого из них.
Enumerables против Iterables
Чтобы понять различие между for...in
и for...of
, важно определить разницу между перечисляемыми и итерациями. Это может быть сложно, поскольку есть некоторое совпадение, и термины часто используются как взаимозаменяемые.
Мне нравится думать о перечисляемых объектах как о прямоугольнике, а о итерируемых объектах - как о квадрате. Следовательно, все итерации являются перечисляемыми; однако не все перечисляемые элементы являются итерируемыми.
Помня об этом, давайте углубимся в их определения.
Сначала мы определим перечислимый. Глагол перечислить определяется как упоминание или подсчет элементов по одному. Применяя это к программированию, перечислимое становится объектом, части которого можно четко идентифицировать и ссылаться на них.
Теперь перейдем к итерируемому. От корневого глагола iterate, определяемого как выполнение в повторении, итерация - это объект, в котором для каждого элемента выполняется один и тот же набор действий.
Так в чем разница? Вот несколько примеров каждого из них, прежде чем мы выделим, что делает перечислимым итерируемым:
- Мешок M & Ms - это бесчисленное множество
- Строка в DMV является повторяющейся
- Стопка книг - это бесчисленное множество
- Ряд книг на полке повторяется
- Объекты JSON перечислимы
- Массивы JSON - итерируемые
Вы определились с ключевым качеством? Это порядок. Итерируемый объект имеет внутренний порядок частей, тогда как перечислимый объект имеет отдельные части, но они неупорядочены.
Использование ‘for… in’
Мы начинаем с for...in
, который используется для перебора перечислимого. Это идеально подходит для подсчета пар ключ-значение в объекте, как в примере ниже.
let person = { "first_name": "Jonathan", "last_name": "Hsu", "medium-handle": "@jhsu98" } for(const key in person) { console.log(key + ": " + person[key]); } /* "first_name: Jonathan" "last_name: Hsu" "medium-handle: @jhsu98" */
Как видите, цикл for...in
устанавливает временную переменную для каждого ключа объекта. Следовательно, в данном случае учитываются идентификаторы.
Использование ‘for… of’
Хорошо, теперь переходим к циклу for...of
. Этот цикл имеет очень похожий синтаксис. Однако итерация требуется после ключевого слова of
- в отличие от требования перечисления с in
.
let scores = [43,58,28,69,38]; for(const item of scores) { console.log(item); } /* 43 58 28 69 38 */
Если мы попытаемся использовать for...of
с перечислимым, ожидайте следующую ошибку:
let person = { "first_name": "Jonathan", "last_name": "Hsu", "medium-handle": "@jhsu98" } for(const item of person) { console.log(item); } /* "TypeError: person is not iterable at gewuhimaza.js:6:84 at https://static.jsbin.com/js/prod/runner-4.1.7.min.js:1:13924 at https://static.jsbin.com/js/prod/runner-4.1.7.min.js:1:10866" */
Я думал, что массивы тоже были перечислимыми
Ты прав! Мы видели, что передача перечислимого в for...of
вызовет ошибку, но передача итерации в for...in
допускается.
let scores = [43,58,28,69,38]; for(const item in scores) { console.log(item); } /* "0" "1" "2" "3" "4" */
Подобно тому, как for...in
подсчитывает идентификаторы объекта, for...in
подсчитывает индексы - думайте о них как об идентификаторах позиции.
Вот и все. Итерируемые объекты - это тип перечислимого типа, при этом дополнительное качество является порядком. Постарайтесь более осознанно описывать свои структуры данных и рассказывать о различиях между for...in
и for...of
.