Урок 12 из 49 · Месяц 2. Git и введение в JavaScript

Циклы, массивы и объекты

Содержание урока

Почти любая программа работает со списками (товары в корзине, сообщения в чате) и с описаниями чего-то одного (пользователь, заказ). В этом уроке разберём циклы — способ повторять действия, массивы — упорядоченные списки, объекты — наборы «ключ: значение», и посмотрим, как из них складываются структуры данных реальных приложений.

Циклы

Цикл — это повторение одного и того же кода несколько раз. Без циклов, чтобы вывести числа от 1 до 100, пришлось бы написать 100 строк console.log. С циклом — три.

Каждый проход цикла называется итерацией.

Цикл for

Самый частый цикл, когда заранее известно, сколько раз повторять:

for (let i = 1; i <= 5; i++) {
  console.log("Итерация номер", i);
}

В скобках три части, разделённые ;:

  1. let i = 1 — начало: создаём счётчик. Выполняется один раз.
  2. i <= 5 — условие: проверяется перед каждой итерацией. Пока true — цикл крутится.
  3. i++ — шаг: выполняется после каждой итерации.

Порядок работы: создать i = 1 → проверить 1 <= 5 → выполнить тело → i++ → проверить 2 <= 5 → … → когда i станет 6, условие ложно, цикл заканчивается.

Пример посложнее — сумма чисел от 1 до 100:

let sum = 0;
for (let i = 1; i <= 100; i++) {
  sum += i;
}
console.log(sum); // 5050

Цикл while

while («пока») повторяет код, пока условие истинно. Удобен, когда количество повторов заранее неизвестно:

let balance = 1000;
let months = 0;

while (balance < 2000) {
  balance = balance * 1.1; // +10% в месяц
  months++;
}

console.log(`Сумма удвоится через ${months} мес.`); // 8 мес.

Цикл do...while

Отличается тем, что тело выполняется хотя бы один раз, а условие проверяется после:

let attempt = 0;
do {
  attempt++;
  console.log("Попытка", attempt);
} while (attempt < 3);

break и continue

  • break — немедленно выйти из цикла;
  • continue — пропустить остаток текущей итерации и перейти к следующей.
for (let i = 1; i <= 10; i++) {
  if (i % 2 === 0) continue; // чётные пропускаем
  if (i > 7) break;          // после 7 останавливаемся
  console.log(i);            // 1, 3, 5, 7
}

Массивы

Массив — упорядоченный список значений. Аналогия: ряд пронумерованных шкафчиков в раздевалке. Нумерация начинается с нуля.

const fruits = ["яблоко", "банан", "киви"];

console.log(fruits[0]);      // "яблоко" — первый элемент
console.log(fruits[2]);      // "киви"
console.log(fruits[5]);      // undefined — такого шкафчика нет
console.log(fruits.length);  // 3 — количество элементов
console.log(fruits[fruits.length - 1]); // "киви" — последний элемент
console.log(fruits.at(-1));  // "киви" — то же, но короче

Индекс последнего элемента всегда length - 1, потому что счёт идёт с нуля.

Изменение массива

const cart = ["хлеб", "молоко"];

cart.push("сыр");        // добавить в конец   → ["хлеб", "молоко", "сыр"]
cart.unshift("вода");    // добавить в начало  → ["вода", "хлеб", "молоко", "сыр"]
cart.pop();              // удалить последний  → ["вода", "хлеб", "молоко"]
cart.shift();            // удалить первый     → ["хлеб", "молоко"]
cart[1] = "кефир";       // заменить по индексу → ["хлеб", "кефир"]

console.log(cart);

Полезные методы

Метод Что делает Пример
includes(x) Есть ли элемент ["a","b"].includes("b") → true
indexOf(x) Индекс элемента или -1 ["a","b"].indexOf("b") → 1
join(sep) Склеить в строку ["a","b"].join(", ") → "a, b"
slice(start, end) Копия части массива [1,2,3,4].slice(1, 3) → [2, 3]
splice(i, n) Удалить n элементов с индекса i изменяет сам массив
reverse() Перевернуть изменяет сам массив

Методы перебора (map, filter, forEach и др.) мы подробно разберём в уроке Методы перебора массива.

Перебор массива циклом

Классический for по индексам:

const prices = [1200, 450, 980];
for (let i = 0; i < prices.length; i++) {
  console.log(`Товар ${i + 1}: ${prices[i]} сом`);
}

Цикл for...of — проще, когда индекс не нужен. Он сразу даёт значения элементов:

const prices = [1200, 450, 980];
let total = 0;

for (const price of prices) {
  total += price;
}
console.log(total); // 2630

Разбор: на каждой итерации в price по очереди попадают 1200, 450, 980. Переменная объявлена через const, потому что внутри одной итерации она не меняется — на следующей это уже новая переменная.

Пример: поиск максимума

const temps = [12, 25, 18, 31, 22];
let max = temps[0];

for (const t of temps) {
  if (t > max) {
    max = t;
  }
}
console.log("Самый жаркий день:", max); // 31

Идея: считаем первый элемент максимумом, затем сравниваем с ним каждый следующий и обновляем, если нашли больше. (Для этой задачи есть и готовое Math.max(...temps) — знак ... разберём в уроке Деструктуризация, spread и rest.)

Объекты

Объект — набор свойств вида «ключ: значение». Если массив — это нумерованные шкафчики, то объект — анкета с подписанными полями.

const user = {
  name: "Нурлан",
  age: 24,
  isAdmin: false,
  skills: ["HTML", "CSS"],
};
  • name, age, isAdmin, skills — ключи (названия свойств);
  • справа от : — значения любого типа, даже массивы и другие объекты;
  • свойства разделяются запятыми; запятая после последнего допустима и удобна.

Чтение и изменение свойств

console.log(user.name);      // "Нурлан" — через точку
console.log(user["age"]);    // 24 — через квадратные скобки

user.age = 25;               // изменить
user.city = "Бишкек";        // добавить новое свойство
delete user.isAdmin;         // удалить свойство

console.log(user.email);     // undefined — свойства нет
console.log("city" in user); // true — проверка, есть ли ключ

Квадратные скобки нужны, когда имя ключа лежит в переменной:

const field = "name";
console.log(user[field]);  // "Нурлан"
console.log(user.field);   // undefined — ищет ключ с именем "field"

Методы объекта

Значением свойства может быть функция — тогда её называют методом:

const counter = {
  value: 0,
  increment() {
    this.value++;
  },
};

counter.increment();
counter.increment();
console.log(counter.value); // 2

this внутри метода — это сам объект, у которого метод вызвали (здесь counter). Функции подробно разберём в уроке Функции, замыкания и колбэки.

Перебор объекта

const product = { title: "Ноутбук", price: 65000, inStock: true };

for (const key in product) {
  console.log(key, "→", product[key]);
}

console.log(Object.keys(product));    // ["title", "price", "inStock"]
console.log(Object.values(product));  // ["Ноутбук", 65000, true]
console.log(Object.entries(product)); // [["title", "Ноутбук"], ["price", 65000], ["inStock", true]]
  • for...in перебирает ключи объекта;
  • Object.keys / values / entries превращают объект в массив, который удобно перебирать через for...of.
for (const [key, value] of Object.entries(product)) {
  console.log(`${key}: ${value}`);
}

Объекты копируются по ссылке

Переменная хранит не сам объект, а ссылку на него — как адрес дома, а не сам дом:

const a = { score: 1 };
const b = a;      // копируем адрес, а не объект
b.score = 100;
console.log(a.score); // 100 — изменили один и тот же объект

Сделать отдельную (поверхностную) копию можно так: const copy = { ...a } — подробнее в уроке про spread.

Структуры данных

Структура данных — способ организовать информацию. На практике чаще всего данные приходят как массив объектов: список товаров, пользователей, задач.

const products = [
  { id: 1, title: "Футболка", price: 900, category: "одежда" },
  { id: 2, title: "Кружка", price: 350, category: "посуда" },
  { id: 3, title: "Худи", price: 2500, category: "одежда" },
];

let clothesTotal = 0;
for (const item of products) {
  if (item.category === "одежда") {
    console.log(`${item.title} — ${item.price} сом`);
    clothesTotal += item.price;
  }
}
console.log("Одежда на сумму:", clothesTotal); // 3400

Разбор:

  1. products — массив, каждый элемент — объект с одинаковыми ключами.
  2. for...of достаёт объекты по одному в item.
  3. item.category — обращаемся к свойству текущего объекта.
  4. Если категория подходит — выводим и прибавляем цену.

Объекты внутри объектов тоже обычное дело:

const order = {
  id: 501,
  customer: { name: "Алина", phone: "+996 700 000 000" },
  items: [
    { title: "Пицца", qty: 2 },
    { title: "Сок", qty: 1 },
  ],
};

console.log(order.customer.name);   // "Алина"
console.log(order.items[0].title);  // "Пицца"
console.log(order.items.length);    // 2

Читайте цепочку слева направо: order → его свойство items (массив) → элемент [0] (объект) → его свойство title.

В JavaScript есть и специальные структуры Map и Set. Например, Set хранит только уникальные значения:

const tags = new Set(["js", "css", "js", "html"]);
console.log(tags.size); // 3 — дубликат "js" отброшен
console.log(tags.has("css")); // true

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

  • Выход за границы массива: i <= arr.length вместо i < arr.length — последняя итерация даст undefined.
  • Индексы с единицы: первый элемент — arr[0], не arr[1].
  • user.key вместо user[key], когда имя ключа в переменной.
  • Опечатка в ключе: user.nmae не вызовет ошибку, а вернёт undefined — проверяйте имена.
  • Ожидание, что const b = a копирует объект — копируется только ссылка.

Практика

  1. Таблица умножения. С помощью вложенных циклов for выведите таблицу умножения от 1 до 5. Ожидаемый результат: строки вида 3 x 4 = 12.
  2. Список покупок. Создайте массив из 4 продуктов, добавьте один в конец, удалите первый и выведите список через join(", "). Ожидаемый результат: строка из 4 продуктов через запятую.
  3. Профиль. Создайте объект student с полями name, age, courses (массив). Добавьте свойство group, выведите все пары «ключ: значение» через Object.entries. Ожидаемый результат: 4 строки в консоли.
  4. Средний балл. Дан массив const grades = [5, 4, 3, 5, 5, 4]. Посчитайте средний балл циклом и выведите количество пятёрок. Ожидаемый результат: 4.33 (через toFixed(2)) и 3.
  5. Склад. Создайте массив из 5 товаров { title, price, qty }. Выведите товары, которых меньше 3 штук, и общую стоимость склада (price * qty по всем товарам). Ожидаемый результат: список «заканчивающихся» товаров и одно число — итог.

Итоги

  • for — когда известно число повторов, while — пока выполняется условие, do...while — хотя бы один раз.
  • break прерывает цикл, continue пропускает итерацию.
  • Массив — список с индексами от 0 до length - 1; push/pop/shift/unshift меняют его.
  • Объект — набор «ключ: значение»; доступ через . или [].
  • for...of перебирает значения массива, for...in и Object.entries — свойства объекта.
  • Реальные данные чаще всего — массив объектов; объекты передаются по ссылке.
Отзыв