← JavaScript/Циклы: while и for#54 из 383← ПредыдущийСледующий →+20 XP
Полезно по теме:Гайд: как учить JavaScriptПрактика: JS базаПрактика: async и сетьТермин: Closure

Циклы: while и for

Когда WhatsApp загружает историю сообщений, он проходит по каждому сообщению и отрисовывает его на экране. Когда Amazon рассчитывает стоимость корзины — проходит по каждому товару и суммирует цены. Когда Spotify генерирует плейлист — перебирает треки и проверяет критерии. Всё это — циклы.

На основе предыдущих уроков

Мы умеем хранить данные в переменных и принимать решения через if/else. Циклы добавляют третий фундаментальный инструмент — повторение.

Какую проблему решают циклы?

Без циклов для обработки 1000 заказов нужно написать 1000 строк одинакового кода. Цикл позволяет написать логику один раз и применить к любому количеству элементов.

for — когда знаешь сколько итераций

Классический цикл с тремя частями в одной строке:

for (начало; условие; шаг) {
  // тело цикла
}

for (let i = 0; i < 5; i++) {
  console.log(i)  // 0, 1, 2, 3, 4
}
  • начало: let i = 0 — выполняется один раз
  • условие: i < 5 — проверяется перед каждой итерацией
  • шаг: i++ — выполняется после каждой итерации
  • for...of — перебор коллекций (самый частый вариант)

    Самый читаемый способ пройтись по массиву:

    const messages = ['Привет!', 'Как дела?', 'Спасибо!']
    for (const message of messages) {
      console.log(message)  // каждое сообщение по очереди
    }

    while — когда не знаешь заранее сколько итераций

    let retries = 0
    while (retries < 3) {
      const success = tryApiCall()  // пытаемся сделать запрос
      if (success) break
      retries++
    }

    break и continue

  • `break` — выйти из цикла немедленно (нашли что искали)
  • `continue` — пропустить текущую итерацию и перейти к следующей
  • for (const item of items) {
      if (item.deleted) continue    // пропускаем удалённые
      if (item.id === targetId) {
        process(item)
        break  // нашли — выходим
      }
    }

    Типичные ошибки

    Ошибка 1: Бесконечный цикл — забыли изменить переменную

    let i = 0
    while (i < 10) {
      console.log(i)
      // забыли i++ — браузер зависнет!
    }
    // Правильно:
    while (i < 10) {
      console.log(i)
      i++
    }

    Ошибка 2: Изменять массив во время перебора

    const arr = [1, 2, 3, 4, 5]
    for (const item of arr) {
      if (item === 3) arr.splice(0, 1)  // опасно! меняем массив в цикле
    }
    // Правильно: создавай новый массив через filter
    const filtered = arr.filter(item => item !== 3)

    Ошибка 3: Начинать индекс с 1 вместо 0

    const fruits = ['яблоко', 'банан', 'апельсин']
    for (let i = 1; i < fruits.length; i++) {  // пропустим 'яблоко'!
      console.log(fruits[i])
    }
    // Правильно: i = 0, массивы индексируются с нуля

    В реальных проектах

    В современном JS циклы for...of и методы массивов (forEach, map, filter) используются намного чаще классического for. Классический for нужен когда важен индекс или нужен точный контроль над итерацией.

    Примеры

    Обработка заказов службы доставки

    const orders = [
      { id: 'ORD-001', customer: 'Алексей', total: 3200, status: 'delivered' },
      { id: 'ORD-002', customer: 'Мария',   total: 890,  status: 'pending' },
      { id: 'ORD-003', customer: 'Иван',    total: 5600, status: 'delivered' },
      { id: 'ORD-004', customer: 'Ольга',   total: 240,  status: 'cancelled' },
      { id: 'ORD-005', customer: 'Пётр',    total: 1100, status: 'delivered' },
    ]
    
    // Считаем статистику за день
    let totalRevenue = 0
    let deliveredCount = 0
    
    for (const order of orders) {
      if (order.status === 'cancelled') continue  // пропускаем отменённые
    
      if (order.status === 'delivered') {
        totalRevenue += order.total
        deliveredCount++
      }
    }
    
    console.log('Доставлено заказов:', deliveredCount)  // 3
    console.log('Выручка:', totalRevenue, 'руб.')       // 9900 руб.
    
    // Найти первый крупный заказ (> 3000)
    let bigOrder = null
    for (const order of orders) {
      if (order.total > 3000) {
        bigOrder = order
        break  // нашли первый — выходим
      }
    }
    console.log('Крупный заказ:', bigOrder?.id)  // 'ORD-001'

    Циклы: while и for

    Когда WhatsApp загружает историю сообщений, он проходит по каждому сообщению и отрисовывает его на экране. Когда Amazon рассчитывает стоимость корзины — проходит по каждому товару и суммирует цены. Когда Spotify генерирует плейлист — перебирает треки и проверяет критерии. Всё это — циклы.

    На основе предыдущих уроков

    Мы умеем хранить данные в переменных и принимать решения через if/else. Циклы добавляют третий фундаментальный инструмент — повторение.

    Какую проблему решают циклы?

    Без циклов для обработки 1000 заказов нужно написать 1000 строк одинакового кода. Цикл позволяет написать логику один раз и применить к любому количеству элементов.

    for — когда знаешь сколько итераций

    Классический цикл с тремя частями в одной строке:

    for (начало; условие; шаг) {
      // тело цикла
    }
    
    for (let i = 0; i < 5; i++) {
      console.log(i)  // 0, 1, 2, 3, 4
    }
  • начало: let i = 0 — выполняется один раз
  • условие: i < 5 — проверяется перед каждой итерацией
  • шаг: i++ — выполняется после каждой итерации
  • for...of — перебор коллекций (самый частый вариант)

    Самый читаемый способ пройтись по массиву:

    const messages = ['Привет!', 'Как дела?', 'Спасибо!']
    for (const message of messages) {
      console.log(message)  // каждое сообщение по очереди
    }

    while — когда не знаешь заранее сколько итераций

    let retries = 0
    while (retries < 3) {
      const success = tryApiCall()  // пытаемся сделать запрос
      if (success) break
      retries++
    }

    break и continue

  • `break` — выйти из цикла немедленно (нашли что искали)
  • `continue` — пропустить текущую итерацию и перейти к следующей
  • for (const item of items) {
      if (item.deleted) continue    // пропускаем удалённые
      if (item.id === targetId) {
        process(item)
        break  // нашли — выходим
      }
    }

    Типичные ошибки

    Ошибка 1: Бесконечный цикл — забыли изменить переменную

    let i = 0
    while (i < 10) {
      console.log(i)
      // забыли i++ — браузер зависнет!
    }
    // Правильно:
    while (i < 10) {
      console.log(i)
      i++
    }

    Ошибка 2: Изменять массив во время перебора

    const arr = [1, 2, 3, 4, 5]
    for (const item of arr) {
      if (item === 3) arr.splice(0, 1)  // опасно! меняем массив в цикле
    }
    // Правильно: создавай новый массив через filter
    const filtered = arr.filter(item => item !== 3)

    Ошибка 3: Начинать индекс с 1 вместо 0

    const fruits = ['яблоко', 'банан', 'апельсин']
    for (let i = 1; i < fruits.length; i++) {  // пропустим 'яблоко'!
      console.log(fruits[i])
    }
    // Правильно: i = 0, массивы индексируются с нуля

    В реальных проектах

    В современном JS циклы for...of и методы массивов (forEach, map, filter) используются намного чаще классического for. Классический for нужен когда важен индекс или нужен точный контроль над итерацией.

    Примеры

    Обработка заказов службы доставки

    const orders = [
      { id: 'ORD-001', customer: 'Алексей', total: 3200, status: 'delivered' },
      { id: 'ORD-002', customer: 'Мария',   total: 890,  status: 'pending' },
      { id: 'ORD-003', customer: 'Иван',    total: 5600, status: 'delivered' },
      { id: 'ORD-004', customer: 'Ольга',   total: 240,  status: 'cancelled' },
      { id: 'ORD-005', customer: 'Пётр',    total: 1100, status: 'delivered' },
    ]
    
    // Считаем статистику за день
    let totalRevenue = 0
    let deliveredCount = 0
    
    for (const order of orders) {
      if (order.status === 'cancelled') continue  // пропускаем отменённые
    
      if (order.status === 'delivered') {
        totalRevenue += order.total
        deliveredCount++
      }
    }
    
    console.log('Доставлено заказов:', deliveredCount)  // 3
    console.log('Выручка:', totalRevenue, 'руб.')       // 9900 руб.
    
    // Найти первый крупный заказ (> 3000)
    let bigOrder = null
    for (const order of orders) {
      if (order.total > 3000) {
        bigOrder = order
        break  // нашли первый — выходим
      }
    }
    console.log('Крупный заказ:', bigOrder?.id)  // 'ORD-001'

    Задание

    Ты разрабатываешь функцию для корзины интернет-магазина. Напиши функцию calcCartTotal(items), которая проходит по массиву товаров и считает общую сумму. Каждый товар — объект с полями price и quantity.

    Подсказка

    for (const item of items) { total += item.price * item.quantity }

    Загружаем среду выполнения...
    Загружаем AI-помощника...