Цикли в JavaScript
Цикли дають змогу залежно від певних умов виконувати деяку дію безліч разів. У JavaScript є такі види циклів:
- for
- for..in
- for..of
- while
- do..while
Цикл for
Цикл for має таке формальне визначення:
for
([ініціалізація лічильника]; [умова]; [зміна лічильника]){
// дії
}
Наприклад, використовуємо цикл for для перебору чисел від 0 до 4:
for(let i = 0; i<5; i++){
console.log(i);
}
console.log("Кінець роботи");
Перша частина оголошення циклу - let i = 0
- створює та ініціалізує лічильник - змінну i. І перед виконанням циклу її значення дорівнюватиме 0. По суті це те ж саме, що й оголошення змінної.
Друга частина - умова, за якої буде виконуватися цикл: i<5
. У цьому випадку цикл виконуватиметься, поки значення i не досягне 5.
Третя частина - i++
- збільшення лічильника на одиницю.
Тобто під час запуску змінна i
дорівнює 0. Це значення відповідає умові i<5
, тому буде виконуватися блок циклу, а саме рядок коду
console.log(i);
Після виконання блоку циклу виконується третя частина оголошення циклу - прирощення лічильника. Тобто змінна i стає рівною 1. Це значення також відповідає умові, тому блок циклу знову виконується. Таким чином, блок циклу спрацює 5 разів, поки значення i не стане рівним 5. Це значення НЕ відповідає умові, тому відбудеться вихід із циклу. І керування програмою перейде до інструкцій, які йдуть після блоку циклу. Консольний вивід програми:
1
2
3
4
Кінець роботи
Кожне окреме повторення циклу називається ітерацією. Таким чином, у цьому випадку спрацюють 5 ітерацій.
При цьому необов'язково збільшувати лічильник на одиницю, можна робити з ним інші дії, наприклад, зменшувати на одиницю:
for(let i = 10; i > 5; i--){
console.log(i);
}
У цьому випадку на консоль виводиться числа від 10 до 6.
Або збільшимо лічильник на 2:
for(let i = 0; i < 10; i+=2){
console.log(i);
}
Тут виводяться на консоль усі парні числа від 0 до 8
При цьому можна опускати різні частини оголошення циклу:
let i = 0;
for(; i < 60;){
console.log(i);
i = i + 10;
}
У цьому випадку змінна i визначена поза циклом. У самому оголошенні циклу є тільки умова, інші дві частини відсутні. Зміна змінної відбувається в самому блоці циклу: вона збільшується на 10. У підсумку на консоль будуть виведені числа 0, 10, 20, 30, 40, 50.
Лічильник зручно використовувати як індекс елементів масиву і таким чином перебирати масив:
const people = ["Tom", "Sam", "Bob"];
for(let i=0; i < 3; i++){
console.log(people[i]);
}
Консольний вивід браузера:
Sam
Bob
Застосування декількох лічильників у циклі
За необхідності можна використовувати кілька лічильників:
for(let i = 1, j=1; i < 5, j < 4; i++, j++){
console.log(i + j);
}
// 1 ітерація: i=1, j=1; i + j = 2
// 2 ітерація: i=2, j=2; i + j = 4
// 3 ітерація: i=3, j=3; i + j = 6
Виконання дій в оголошенні циклу
Варто зазначити, що третя частина циклу, де зазвичай відбувається зміна лічильника, в реальності являє собою довільну дію, яка виконується після завершення циклу. Так, ми можемо написати таким чином:
for(let i = 0; i < 5; console.log(i++));
console.log("Кінець роботи");
Тут не визначено блоку циклу, а самі дії циклу визначено в третій частині заголовка циклу - console.log(i++)
Аналогічно в першій частині визначення циклу - ініціалізації ми можемо виконувати деякі дії, а не обов'язково тільки оголошення лічильника:
let i=0;
for(console.log("Init"); i < 5; i++){
console.log(i);
}
Тут визначення лічильника винесено поза циклом, а в ініціалізаційній частині циклу на консоль виводиться рядок. Виведення браузера:
0
1
2
3
4
Вкладені цикли
Одні цикли можуть усередині себе містити інші:
for(let i=1; i <= 5; i++){
for(let j = 1; j <=5; j++){
console.log(i * j);
}
}
Тут один цикл включається в себе інший. У зовнішньому циклі визначається змінна i. Спочатку вона дорівнює 1 і це значення відповідає умові циклу(i <=5
), тому буде виконуватися блок циклу, який містить внутрішній цикл.
У внутрішньому циклі визначається змінна-лічильник j, яка спочатку дорівнює 1, і потім внутрішній цикл виконує 5 ітерацій, поки змінна j не дорівнюватиме 5.
Після того, як блок зовнішнього циклу завершено, змінна i збільшується на 1 і стає рівною 2, що знову ж таки відповідає умові. І знову виконується блок зовнішнього циклу. У цьому блоці знову виконуються п'ять ітерацій внутрішнього циклу. І так далі. У підсумку внутрішній цикл буде виконуватися 25 разів.
Використовуючи вкладені цикли і кілька лічильників можна перебирати багатовимірні масиви:
const people = [[["Tom", 39], ["Sam", 28],["Bob", 42]];
for(let i=0; i < 3; i++){ // перебираємо двовимірний масив
for(let j=0; j < 2; j++){ // перебираємо вкладені масиви
console.log(people[i][j]);
}
console.log("================="); // для розділення елементів
}
Тут масив people представляє двовимірний масив із 3-х елементів, де кожен елемент представляє, своєю чергою, підмасив із 2-х елементів - умовно імені та віку користувача. У зовнішньому циклі визначаємо лічильник i для проходу по всіх підмасивах у двовимірному масиві people, а у внутрішньому циклі визначаємо лічильник j для проходу по всіх елементах кожного підмасиву. Консольний вивід:
39
=================
Sam
28
=================
Bob
42
=================
Цикл while
Цикл while виконується доти, доки деяка умова істинна. Його формальне визначення:
while(умова){
// дії
}
Знову ж таки виведемо за допомогою while числа від 1 до 5:
let i = 1;
while(i <=5){
console.log(i);
i++;
}
Цикл while тут виконуватиметься, поки значення i не стане рівним 6.
do..while
У циклі do спочатку виконується код циклу, а потім відбувається перевірка умови в інструкції while. І поки ця умова істинна, цикл повторюється. Наприклад:
let i = 1;
do{
console.log(i);
i++;
}while(i <= 5)
Тут код циклу спрацює 5 разів, поки i не стане рівним 5. При цьому цикл do гарантує хоча б одноразове виконання дій, навіть якщо умова в інструкції while не буде істинною.
Оператори continue і break
Іноді буває необхідно вийти з циклу до його завершення. У цьому випадку ми можемо скористатися оператором break:
for(let i=1; i <= 6; i++){
if(i===4) break;
console.log(i);
}
console.log("Кінець роботи");
Цей цикл збільшує змінну i з 1 до 6 включно, тобто згідно з умовою циклу блок циклу має виконуватися 6 разів, тобто провести 6 ітерацій. Однак оскільки в блоці циклу відбувається перевірка if(i===4) break;
, то, коли значення змінної i досягне 4, то ця умова перерве виконання циклу за допомогою оператора break. І цикл завершить роботу.
2
3
Кінець роботи
Якщо нам треба просто пропустити ітерацію, але не виходити з циклу, ми можемо застосовувати оператор continue. Наприклад, змінимо попередній приклад, тільки замість break
використовуємо оператор continue:
for(let i=1; i <= 6; i++){
if(i===4) continue;
console.log(i);
}
console.log("Кінець роботи");
У цьому випадку, коли значення змінної i стане рівним 4, то вираз i===4
поверне true
, тому виконуватиметься конструкція if(i===4) continue;
. За допомогою оператора continue вона завершить поточну ітерацію, інструкції циклу, що йдуть далі, не будуть виконуватися, а відбудеться перехід до наступної ітерації:
2
3
5
6
Кінець роботи
for..in
Цикл for..in призначений головним чином для перебору об'єктів. Його формальне визначення:
for
(властивість in
об'єкт) {
// дії
}
Цей цикл перебирає всі властивості об'єкта. Наприклад:
const person = {ім'я: "Том", вік: 37};
for(prop in
person){
console.log(prop);
}
Тут перебирається об'єкт person, який має дві властивості - name і age. Відповідно на консолі ми побачимо:
age
Отримавши властивості і використовуючи спеціальний синтаксис об'єкт[властивість]
, ми можемо отримати значення кожної властивості:
const person = {ім'я: "Том", вік: 37};
for(prop in
person){
console.log(prop, person[prop]);
}
Консольний вивід:
age 37
Цикл for...of
Цикл for...of призначений для перебору наборів даних. Наприклад, рядок являє собою фактично набір символів. І ми можемо перебрати його за допомогою цього циклу:
const text = "Hello";
for(char of text){
console.log(char);
}
У підсумку цикл перебирає всі символи рядка text
і поміщає кожен поточний символ у змінну ch
, значення якої потім виводиться на консоль.
e
l
l
o
Іншим прикладом може бути перебір масиву:
const people = ["Tom", "Sam", "Bob"];
for(const person of people) {
console.log(person);
}
У цьому випадку цикл перебирає елементи масиву people. Кожен елемент послідовно поміщається в константу person
. І далі ми можемо вивести її значення на консоль:
Sam
Bob