Назначение и виды циклов

Циклы – это конструкции языка JavaScript, которые применяются, когда необходимо выполнить некоторые действия несколько раз.

На языке JavaScript существуют различные виды циклов, которые по сути дела выполняют одно и тоже. Просто одни задачи решаются более просто с помощью одних циклов, а другие – с помощью других.

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

  • for;
  • while;
  • do...while;
  • for...in.

Цикл for

Данный цикл в основном используется когда известно точное количество повторений. Этот цикл ещё называют циклом со счётчиком.

Синтаксис цикла «for»:

for (инициализация; условие; финальное выражение) {
  /* тело цикла */
}
Алгоритм работы цикла for в JavaScript

Основные части конструкции цикла «for»:

  • инициализация - это выражение, которое выполняется один раз перед выполнением цикла; обычно используется для инициализации счётчика;
  • условие - это выражение, истинность которого проверяется перед каждой итерацией; если выражение вычисляется как истина> то выполняется итерация, в противном случае цикл «for» завершает работу;
  • финальное выражение - это выражение, которое выполняется в конце каждой итерации; обычно используется для изменения счетчика;
  • тело цикла - инструкции, выполнение которых нужно повторять.

Рассмотрим пример цикла, который выведет в консоль числа от 1 до 8:

// цикл «for» от 1 до 8, с шагом 1
for (var i = 1; i <= 8; i++) {
  console.log(i);
}

В этом примере:

  • инициализация: var i = 1 (объявление переменной i и присвоение ей значения 1);
  • условие выполнения цикла: i <= 8 (пока значение переменной i меньше или равно 8);
  • финальное выражение, которое нужно выполнять в конце каждой итерации: i++ (увеличение значение переменной i на 1);
  • инструкция, которую нужно выполнять: console.log(i) (выведение значения счётчика в консоль).

При этом если тело цикла состоит из одной инструкции, то её можно не заключать в фигурные скобки.

Т.е. пример приведённый выше можно записать ещё так:

// цикл «for» от 1 до 8, с шагом 1
for (var i = 1; i <= 8; i++) console.log(i);

Необязательные части цикла цикла «for».

В «for» все части цикла являются не обязательными.

Например, можно пропустить выражение инициализации:

var i = 1;
// цикл «for»
for (; i <= 8; i++) {
  console.log(i);
}

В этом случае инициализацию переменной можно вынести за пределы цикла.

Условие в «for» тоже является не обязательным. Без условия цикл будет выполняться бесконечное количество раз. В этом случае чтобы его прервать (выйти из цикла) необходимо использовать инструкцию break.

// цикл «for»
for (var i = 1; ; i++) {
  if (i >= 8) { // условие прерывания цикла
    break;
  }
  console.log(i);
}

Финальное выражение в «for» также является не обязательным. Счётчик цикла в этом случае можно, например, изменять в теле.

// цикл «for»
for (var i = 1; i <= 8; ) {
  console.log(i);
  i++; // увеличение счетчика на 1
}

В «for» можно вообще опустить 3 выражения (бесконечный цикл):

var i = 1;
// цикл «for»
for (;;) {
  if (i >= 8) {
    break;
  }
  console.log(i);
  i++;
}

Кроме этого, в качестве тела цикла «for» можно использовать пустое выражение (;). Это используется, когда вам не нужно выполнять ни одной инструкции.

Например:

var
  arrA = [8, 12, 24],
  arrB = [];
for (i = 0; i < arrA.length; arrB[i] = arrA[i++] / 2) ;
console.log(arrB); // [4, 6, 12]

Пустое выражение в этом случае рекомендуется дополнительно снабжать комментарием:

// сумма чисел в массиве
var arr = [2, 7, 3];
for (var i = 0, length = arr.length, sum = 0; i < length; sum += arr[i++]) /* пустое выражение */ ;
// выведем сумму чисел в консоль:
console.log(sum); // 12

Пример использования цикла «for» для перебора элементов массива:

var arr = ["a", "b", "c"]; // массив
for (var i = 0, length = arr.length; i < length; i++) {
  console.log(arr[i]);
}

Пример, в котором выведем таблицу умножения в консоль. Для реализации этого примера будем использовать вложенные циклы.

Пример на JavaScript - Вывод таблицы умножения в консоль с использованием вложенных циклов
var output = '';
for (var i = 1; i <= 9; i++) {
  for (var j = 1; j <= 9; j++) {
    output += ' ' + i * j;
    if (i * j < 10) {
      output += ' ';
    }
  }
  console.log(output);
  output = '';
}

Цикл называется вложенным, если он находится в теле другого цикла.

Цикл while

Данный цикл предназначен для многократного выполнения одних и тех же инструкций до тех пор, пока истинно некоторое условие. Цикл «while» в основном используется, когда количество повторений заранее не известно.

while (условие) {
  /* тело цикла */
}
Алгоритм работы цикла while в JavaScript

Истинность условия проверяется перед каждым выполнением. Если перед первой итерацией условие ложно, то цикл не выполнится ни разу.

Пример, в котором выведем в консоль чётные числа в диапазоне от 1 до 8:

// объявим переменную а и присвоим ей значение 1
var a = 1;
//цикл while с условием a <= 8
while (a <= 8) {
  // если число чётное (остаток от деления на 2 равен 0), то...
  if (a % 2 == 0) {
    // пропустим дальнейшее выполнение текущей итерации и перейдём к следующей
    continue;
  }
  // выведем значение переменной a в консоль
  console.log(a);
  // увеличим значение переменной a на 1
  a++;
}

Цикл do...while

Цикл «do...while», также как и цикл «while», выполняет одни и те же инструкции до тех пор, пока указанное условие истинно. Но в отличие от «while» в «do...while» условие проверяется после выполнения инструкций. Поэтому цикл «do...while» в любом случае выполнится не меньше одного раза, даже если условие изначально ложно.

Алгоритм работы цикла do...while в JavaScript
do {
  /* тело цикла */
} while (условие)

Пример, в котором выведем в консоль сумму чисел, которые будем запрашивать у пользователя с помощью функции prompt:

// num – переменная для хранения числа, введённого пользователем
// sum – переменная для хранения суммы чисел  
var num, sum = 0;
// цикл «do...while»
do {
  // запросим у пользователя данные и приведём их к числу
  num = +prompt ('Введите число', '');
  // если то, что ввёл пользователь после приведения является числом, то...
  if (num) {
    // прибавим к сумме число, введённое пользователем
    sum += data;
  }
// если num приводится к истине, то выполняем ещё итерацию
} while (num);  

Цикл for...in

Цикл «for...in» предназначен для перебора перечисляемых имён свойств объекта.

Свойства объекта, которые не относятся к перечисляемым, не участвуют в цикле.

Например, объект (массив) созданный с использованием функции-конструктора Array или его литеральной записи имеет не перечисляемые свойства от Array.prototype и Object.prototype, такие как indexOf(), some(), toString() и др. Они не будут участвовать в цикле.

// key – переменная, которая будет принимать имена свойств объекта
//  object – объект, который нужно перебрать
for (key in object) {
  /* тело цикла */
}

Переберём свойства объекта, созданного с помощью литеральной записи:

let car = {
  manufacturer: 'Ford',
  model: 'Fiesta',
  color: 'black'
};
for (let propName in car) {
  // propName – имя свойства
  // car[propName] – значение свойства
  console.log(propName + ' = ' + car[propName]);
}
// в консоль будет выведено: manufacturer = Ford, model = Fiesta, color = black

Кроме этого, следует отметить, что цикл for...in проходит не только по перечисляемых свойствам этого объекта, но и наследуемых.

let item = {
  a: 1,
  b: 2
}
let newItem = Object.create(item);
newItem.c = 3;
newItem.d = 4;
for (let propName in newItem) {
  console.log(propName);
}
// в консоли будет выведено: a, b, c, d

Если вам наследуемые свойства не нужно учитывать, то их можно пропустить:

for (let propName in newItem) {
  // переходим к следующей итерации, если текущее свойство не принадлежит этому объекту
  if(!newItem.hasOwnProperty(propName)) {
    continue;
  }
  console.log(propName);
}
// в консоли будет выведено: c, d

Использование цикла for... in для перебора массива. В массиве свойствами являются числовые индексы.

// массив
var arr = ["Rock", "Jazz", "Classical", "Hip Hop"];
// перебор массива с помощью цикла for in
for (let index in arr) {
  // index - индекс элемента массива
  // arr[index] – значение элемента
  console.log(arr[index]);
}
// в результате в консоль будет выведено: "Rock", "Jazz", "Classical", "Hip Hop" 

Цикл for...in проходит по свойствам в произвольном порядке. Поэтому цикл for...in для перебора массива, если важен порядок символов, лучше не использовать.

Инструкции break и continue

Внутри тела цикла можно использовать специальные инструкции: break и continue.

Инструкция «break» предназначена для прекращения выполнения текущего цикла. Другими словами, она осуществляет выход и передачу управления инструкции, идущей после этого цикла.

Пример, в котором завершим цикл по перебору элементов массива, если его текущий элемент не будет являться числом:

// массив
var arr = [5, 3, "a", 4, "b", 16];
// цикл «for» для перебора массива arr
for (var i = 0, length = arr.length; i < length; i++) {
  // если текущий элемент массива не является числом, то...
  if (typeof arr[i] !== 'number') {
    // прерываем выполнение цикла
    break;
  }
  // выводим текущий элемент массива в консоль
  console.log(arr[i]);
}
// в результате в консоль будет выведено: 5, 3

Инструкция «continue» предназначена для прекращения дальнейшего выполнения кода и перехода к следующей итерации цикла.

Пример, в котором выведем в консоль порядковые номера символов «а» и «о», встречающихся в слове «программирование»:

//строка
var str = 'программирование';
// цикл "for" для перебора символов строки 
for (var i = 0, length = str.length; i < length; i++) {
  // если текущий символ не равен а и о, то...
  if (arr[i] !== 'а' && arr[i] !== 'о') {
    // прекращаем выполнение текущей итерации и переходим к следующей
    continue;
  }
  // выводим в консоль порядковый номер символа
  console.log(arr[i]);
}
// данный цикл выведет в консоль: 3, 6, 11, 13