@Ivanushka255

Все циклы, кроме for..in, могут работать только с итерируемыми объектами?

Объект может считаться итерируемым, если у него есть ф-ция Symbol.iterator. Такой объект может перебрать for..of.

Вопрос: получается, что все циклы, кроме for..in (может работать с неитерируемым Object), работают только с итерируемыми объектами (т.е. теми, которые имеют метод Symbol.iterator)? ...Object из всех имеющихся циклов может работать только for..in?
  • Вопрос задан
  • 134 просмотра
Пригласить эксперта
Ответы на вопрос 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
С итерируемыми объектами работают только циклы for-of и for-await-of.

В современном JS есть следующие виды циклов:

1. while - цикл с условием
// где condition - это некоторое выражение, которое можно скастовать к boolean
while (condition) {
}
Данный цикл выполняется, пока условие condition истинно.

2. do-while - цикл с постусловием
do {
} while (condition);
Данный цикл выполняется как минимум 1 раз, условие condition проверяется после тела цикла и если оно истинно - запускается следующая итерация.

3. for - цикл с инициализацией, условием и финальным выражением
for (init; condition; final_expression) {
}

// основное применение - это цикл со счетчиком, но в целом мы не ограничены в применении
for (let i = 0; i < 10; ++i) {
}
Перед циклом выполняется init, который может быть выражением или оператором объявления переменных (var, let, const). Перед каждой итерацией проверяется условие condition, пока это условие истинно - цикл будет выполняться. После каждой итерации выполняется final_expression.

4. for-in - цикл по ключам объекта
// где object - это некоторое выражение, которое можно скастовать к типу object
for (const key in object) {
}
Данный цикл перебирает все перечислимые ключи самого объекта и всех объектов из его цепочки прототипов. Может работать медленно, а ключи из прототипа обычно не требуются, поэтому данный цикл не рекомендуется использовать.

5. for-of - цикл по итерируемым объектам
// где iterable - это некоторый объект с методом Symbol.iterator
for (const value_variable of iterable) {
}
Перед итерацией создает итератор вызывая iterable[Symbol.iterator](), перед каждой итерацией дергает метод next у итератора, работает пока в возвращаемом из метода next объекте поле done не станет true, подставляет поле value в переменную value_variable. Цикл в примере выше можно реализовать в виде обычного for:
{
  const iter = [1, 2, 3][Symbol.iterator]();
  for (let {done, value} = iter.next(); !done; ({done, value} = iter.next())) {
    const value_variable = value;
    {
      // тело исходного цикла
    }
  }
}


6. for-await-of - цикл по асинхронно итерируемым объектам
// где iterable - это некоторый объект с методом Symbol.asyncIterator или методом Symbol.iterator
for await (const value_variable of iterable) {
}
Перед итерацией создает итератор, одним из следующих способов:
Если в объекте iterable есть метод Symbol.asyncIterator - то вызывает его.
В противном случае вызывает метод Symbol.iterator.
В остальном работает как for-of, с той разницей, что дополнительно применяет оператор await к значению итератора и в value_variable попадает то, что вернул данный await.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы