Урок 5. Циклы for и while в JavaScript
Теория
Циклы используются для того, чтобы некоторый участок кода выполнился несколько раз подряд.
Зачем это нужно - представьте, что вам нужно возвести в квадрат 100 элементов массива. Если обращаться к каждому элементу отдельно по его ключу - это займет 100 строчек кода, и для того, чтобы написать этого код, нужно будет потратить довольно много времени.
Но это не нужно - у нас есть возможность сделать так, чтобы JavaScript за нас выполнил некоторую операцию нужное количество раз. Например, возвел все элементы массива в квадрат.
Делается это с помощью циклов.
Цикл while
Цикл while будет выполняться до тех пор, пока верно (истинно) выражение, переданное ему параметром. Смотрите синтаксис:
while(пока выражение истинно){выполняем этот код циклически; в начале каждого цикла проверяем выражение в круглых скобках}
/*Цикл закончится, когда выражение перестанет быть истинным. Если оно было ложным изначально, то он не выполнится ни разу!*/
В принципе, цикл while может выполняться бесконечно (но это приведет к зависанию скрипта!), достаточно передать ему выражение, которое никогда не станет ложным. Например, так:
test=true;
while(test===true){/*Написанный здесь код будет выполняться 'вечно' (пока скрипт не будет остановлен принудительно). Не стоит это повторять, это приведет к зависанию сервера!*/}
Давайте последовательно выведем с помощью цикла while числа от 1 до 5:
i=0;//счетчик цикла
while(i<5){/*С помощью оператора ++ увеличиваем i на 1 при каждом проходе цикла.*/i++;alert(i);}
Обратите внимание на переменную i, она является так называемым счетчиком цикла. Счетчики используются для того, чтобы подсчитывать, сколько раз выполнился цикл. Кроме того, они выполняют вспомогательную роль, в нашей задаче использовался счетчик, чтобы вывести цифры от 1 до 5.
Для счетчиков принято использовать буквы i, j, k.
Цикл for
Цикл for является альтернативой while. Он более сложен для понимания, но чаще всего его любят больше, чем while за то, что он занимает меньше строчек.
for(начальные команды;условие окончания цикла;команды после прохода цикла){тело цикла}
Начальные команды - это то, что выполнится перед стартом цикла. Они выполнятся только 1 раз. Обычно там размещают начальные значения счетчиков, пример: i=0.
Условие окончания цикла - пока оно истинное, цикл будет работать, пример: i<10.
Команды после прохода цикла - это команды, которые будут выполнятся каждый раз при окончании прохода цикла. Обычно там увеличивают счетчики, например: i++.
Давайте с помощью цикла for выведем последовательно числа от 0 до 9:
/*В начале цикла i будет =0, цикл будет выполнятся пока i<10, после каждого прохода к i прибавляется 1:*/
for(i=0;i<10;i++){
alert(i);}//Выведет 0,1,2,…9
Цикл без тела
Фигурные скобки в циклах можно не указывать - в этом случае цикл выполнит только одну строку под ним (не рекомендую так делать, часто приводит к ошибкам):
for(i=0;i<10;i++)//<---точки с запятой нет
alert(i);//Выведет 0,1,2,…9
А вот если после ) поставить точку с запятой - цикл закроется и следующая строка в него не попадет, получится так называемый цикл без тела, который в нашем случае просто прокрутится и в результате изменит значение переменной i:
for(i=0;i<10;i++);//<---точка с запятой есть
alert(i);//Выведет 9
Такой цикл иногда используется, вы увидите примеры его применения при разборах задач на циклы.
Несколько команд в цикле for
Если нам необходимо выполнить несколько команд в круглых скобках - указываем их через запятую:
for(i=0,j=2;i<10;i++,j++,i=i+j){}
Разберем приведенный цикл: до прохода цикла выполнятся 2 команды: var i=0,j=2 (обратите внимание на то, что var тут пишется 1 раз), а после каждой итерации - целых 3: i++,j++,i=i+j.
Этот пример с точки зрения программирования никакой особой пользы не несет, просто схематически показывает, что так можно делать.
Цикл for для массивов
Циклом for можно последовательно перебрать элементы массива. Делается это так:
a=[1,2,3,4,5];for(i=0;i<=a.length-1;i++){alert(a[i]);}//Выведет 1,2,3,4,5
Ключевым моментом является то, что мы делаем перебор от 0 до длины массива минус 1 (т.к. номер последнего элемента массива на 1 меньше его длины).
Можно не отнимать 1, а место <= сделать <:
a=[1,2,3,4,5];for(i=0;i<a.length;i++){alert(a[i]);}//Выведет 1,2,3,4,5
Цикл for-in
Для перебора объекта используется так называемый цикл for-in. Давайте посмотрим, как он работает.
Пусть у нас дан такой объект:
o={Коля:200,Вася:300,Петя:400};
Давайте выведем его ключи. Для этого используем такую конструкцию: for(k in o), где o - это объект, который мы перебираем, а k - это переменная, в которую последовательно будут ложится ключи объекта (ее название может быть любым, какое придумаете - такое и будет).
Т.е. в данном цикле не надо указывать условие окончания, он будет перебирать ключи объекта, пока они не закончатся.
Итак, вот так мы выведем все ключи объекта (по очереди):
o={Коля:200,Вася:300,Петя:400};for(k in o){alert(k);}//Выведет 'Коля','Вася','Петя'
Если нам нужны не ключи, а значения, нужно обратиться к нашему объекту по ключу, вот так: o[k].
Как это работает: в переменной k сначала будет 'Коля', т.е. o[k] в данном случае все равно, что o['Коля'], при следующем проходе цикла в переменной k будет 'Вася' и так далее.
Итак, выведем все элементы объекта:
o={Коля:200,Вася:300,Петя:400};for(k in o){alert(o[k]);}//Выведет 200,300,400
Инструкция break
Иногда нам необходимо прервать выполнение цикла досрочно, в случае с циклом for это значит до того, как цикл переберет все элементы массива.
Зачем такое может понадобится? Например, перед нами стоит задача выводить элементы массива до тех пор, пока не встретится число 3. Как только встретится, цикл должен завершить свою работу.
Такое можно сделать с помощью инструкции break. Если выполнение цикла дойдет до нее, цикл закончит свою работу.
Давайте решим приведенную выше задачу, оборвем цикл, как только нам встретится число 3:
a=[1,2,3,4,5];for(var i=0;i<a.length;i++){if(a[i]===3){break;/*выходим из цикла*/}else{alert(arr[i]);}}
Инструкция continue
Существует также инструкция continue, при достижении которой цикл начинает новую итерацию. Иногда может быть полезна для упрощения кода, хотя практически всегда задачу можно решить и без нее.
Практика
Примеры решения задач
Задача
Вывести числа от 1 до 50.
Решение: воспользуемся циклом while:
i=1;while(i<=50){document.write(i+', ');i++}
Можно также воспользоваться и циклом for:
for(i=1;i<=50;i++){document.write(i+', ')}
Задача
Дан массив с элементами [1,2,3,4,5]. Циклом for вывести все эти элементы.
Решение: будем повторять цикл for от 0 до номера последнего элемента массива. Этот номер на 1 меньше количества элементов в массиве, которое можно найти с помощью свойства length таким образом: a.length.
Чтобы цикл прокрутился на 1 меньше длины массива, в условие окончания мы поставим <, а не <=.
К элементам массива обращаться так: a[i]. Переменная i - это счетчик цикла, который будет меняться от 0 до a.length (не включительно). Так последовательно выведем все элементы массива:
a=[1,2,3,4,5];for(i=0;i<a.length;i++){document.write(a[i]+',')}
Задача
Дан массив с элементами [2,3,4,5]. Циклом for найти произведение элементов этого массива.
Решение: для таких задач существует стандартное решение, которое заключается в том, что цикл for перебирает элементы массива и их произведения последовательно записываются в переменную r (нарастающим итогом):
r=1;a=[2,3,4,5];for(i=0;i<a.length;i++){r=r*a[i]}document.write(r)
Как это работает: изначально переменная r имеет значение 1, затем при 1-м проходе цикла в нее записывается ее текущее содержимое (это 1), умноженное на 1-й элемент массива (это 2). Получится, что в r запишется 1*2 и теперь там будет лежать число 2.
При следующем проходе цикла в r запишется текущее значение r, умноженное на 2-й элемент массива (т.е. 2*3=6). И так далее, пока массив не закончится.
Можно переписать строчку r=r*a[i] через *= для краткости:
r=1;a=[2,3,4,5];for(i=0;i<a.length;i++){r*=a[i]}document.write(r)
Задача. Цикл for-in
Дан объект o с ключами 'Минск','Москва','Киев' с элементами 'Беларусь','Россия','Украина'. Циклом for-in вывести строки формата: 'Минск - это Беларусь'.
Решение: Для начала выведем все ключи объекта (это названия городов):
o={'Минск':'Беларусь','Москва':'Россия','Киев':'Украина'};for(var k in o){document.write(k)}
Выведем все значения объекта (это страны):
o={'Минск':'Беларусь','Москва':'Россия','Киев':'Украина'};for(var k in o){document.write(o[k])}
Сформируем строки в формате:
o={'Минск':'Беларусь','Москва':'Россия','Киев':'Украина'};for(var k in o){document.write(k+' - это '+o[k]+'. ')}
Задачи для решения
Циклы while и for
Решить эти задачи сначала циклом while и циклом for.
Вывести числа от 1 до 100.
Вывести числа от 11 до 33.
Вывести четные числа от 0 до 100.
Циклом найти сумму чисел от 1 до 100.
Работа с for для массивов
Дан массив с элементами [1,2,3,4,5]. Циклом for вывести все эти элементы.
Дан массив с элементами [1,2,3,4,5]. Циклом for найти сумму элементов этого массива. Записать ее в переменную r.
Работа с for-in
Дан объект o. Циклом for-in вывести ключи и элементы этого объекта.
obj={green:'зеленый',red:'красный',blue:'голубой'}
Дан объект o с ключами Коля, Вася, Петя с элементами '200','300','400'. Циклом for-in вывести строки в формате: 'Коля - зарплата 200 руб'.
Задачи
Дан массив с элементами 2,5,9,15,0,4. Циклом for и оператора if вывести столбец тех элементов массива, которые больше 3-х, но меньше 10.
Дан массив с числами. Числа могут быть положительны и отрицательны. Найти сумму положительных элементов массива.
Дан массив с элементами 1,2,5,9,4,13,4,10. Циклом for и оператором if проверить, есть ли в массиве элемент со значением 4. Если есть, вывести 'Есть' и выйти из цикла, если нет, ничего не делать.
Дан массив числами: [10,20,30,50,235,3000]. Вывести только те числа, которые начинаются на цифру 1 или 5.
Дан массив с элементами 1,2,3,4,5,6,7,8,9. Циклом for создать строку '-1-2-3-4-5-6-7-8-9-'.
Составить массив дней недели. Циклом for вывести все дни недели, а выходные дни вывести жирным.
Составить массив дней недели. Циклом for вывести все дни недели, а текущий день вывести курсивом. Текущий день должен храниться в переменной d.
Дано число n=888. Делить его на 2 столько раз, пока результат деления не станет меньше 50. Какое число получится? Посчитать количество итераций, необходимых для этого (итерация - это проход цикла), и записать его в переменную n.