Управление циклами

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

Создание бесконечного цикла

Циклы for и while позволяют достаточно детально управлять выполнением операций. В некоторых случаях, при неосторожности и невнимательности, это порождает сложные проблемы. Взгляните на листинг 15.1.

Листинг 15.1. Пример бесконечного цикла


1:    while (j<10) {
2:    n++;
3:    values[n] = 0;
4:    }
                   

В этом примере умышленно сделана одна ошибка. Условие выполнения цикла определяется переменной j. Но, в то же время, эта переменная не изменяется и не влияет на условие. Таким образом получен бесконечный цикл. Выполнение этого цикла может прервать только пользователь или возниконовение ошибки.

Бесконечные циклы прерываются пользователем только при закрытии браузера. Некоторые бесконечные циклы не позволяют закрывать браузер или вызвать ошибку.

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

В зависимости от типа и версии браузера бесконечный цикл может вызвать "зависание" браузера, когда пользователь не может им управлять. Всегда предусматривайте в циклах процедуру выхода на случай их преобразования в бесконечные периодично повторяющиеся структуры.

Иногда бесконечный цикл необходимо создать умышленно. Это вызвано необходимостью постоянного выполнения программы до прерывания ее пользователем. Процедура выхода из бесконечного цикла предусматривает использование оператора break. Вот как создается бесконечный цикл:

while (true) {

Поскольку значение true - это не условие, JavaScript будет бесконечно продолжать искать условие выхода из цикла.

Прерывание цикла

Существует один надежный способ выхода из цикла. В тело цикла после операторов действия необходимо добавить оператор break. Листинг 15.2 иллюстрирует пример использования оператора break.

Листинг 15.2. Прерывание цикла оператором break


1:    while (true) {
2:    n++;
3:    if (values[n] ==1) break;
4:    }
                   

Оператор while задает бесконечный цикл. Оператор if проверяет значения элементов массива. Если среди значений находится единица, то выполнение цикла прерывается.

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

Прерывание текущей итерации цикла

Повысить управляемость циклами позволяет еще один оператор - continue. Это оператор, который позволяет прервать выполнение операций текущей итерации цикла и продолжить их выполнение со следующей итерации. В листинге 15.3 приведен пример использования этого оператора.

Листинг 15.3. Прерывание выполнения операций цикла


1:    for (i=1; i<21; i++) {
2:    if (score[i]==0) continue;
3:    document.write("Номер студента ",i, "оценка: ", score[i], "<BR>");
4:    }
                   

В этом листинге приведен пример цикла for, используемого для вывода оценок 20 студентов, данные о которых сохранены в массиве score. Оператор if используется для сравнения значения оценки с нулем. Предполагается, что оценка 0 определяет студента, который не сдавал тест. В этом случае выполнение цикла продолжается, но результат отсутствующего на тесте студента не распечатывается.

Использование цикла for...in

Мы переходим к рассмотрению последнего типа циклов в JavaScript. Цикл for...in более гибкий, нежели привычные циклы for и while. Он специально разработан для выполнения операций со свойствами объектов.

Например объект navigator имеет свойства, описывающие параметры браузера. Для отображения свойств объекта также проще всего использовать цикл for...in:


for (i in navigator) {
document.write("Свойство: ", i);
document.write(" Значение: ", navigator[i], "<BR>");
}
                   

Как и обычный цикл for этот тип цикла требует использования индекса (в нашем примере это i). Каждая итерация цикла приводит к определению нового значения переменной-индексу, соответствующего другому свойству объекта. Таким образом очень удобно управлять свойствами объектов.

Управление массивами

Чтобы окончательно понять, для чего используются циклы, давайте вместе создадим сценарий, который управляет массивом значений. (По мере создания сценария вы поймете, как сложно было бы создать его, не использую циклы.)

Создадим простой цикл, который запрашивает имена пользователей. После введения всех имен пользователей отобразим их в виде нумерованного списка. В самом начале сценария объявим некоторые переменные:

names = new Array();
i = 0;

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

Для создания запроса на введение имен используйте оператор prompt. Чтобы автоматизировать процедуру ввода, используйте все тот же цикл. Если в массив имен будет заноситься по меньшей мере одно имя, то используйте цикл do:


do {
  next = prompt("Введите следующее имя");
  if (next > " ") names[i] = next;
  i = i + 1;
  }
while (next > " ");
                   

Этот цикл отображает запрос на введение значения строковой переменной next. После введения имени (и если оно больше пробела) оно сохраняется в виде следующего элемента массива names. Запрос отображается на экране до тех пор, пока пользователь не прекратит вводить имена или щелкнет на кнопке Cancel (Отмена).

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

document.write("<H2>" + (names.length) + " введенных имени.<H2>");

Этот оператор отображает свойство length массива имен names, для выразительности выделенное заголовком второго уровня.

Далее отобразим все сохраненные в массиве имена в порядке их введения. Поскольку мы обрабатываем массив, давайте использовать цикл for...in:


document.write("<OL>");
for (i in names) {
   document.write("<LI>" + names[i] + "<BR>");
}
document.write("</OL>");
                   

Счетчик принимает значения номеров элементов массива. Имя пользователя распечатывается с тегом <LI>, представляющим элемент массива в виде элемента упорядоченного списка.

Листинг 15.4 содержит программный код всего документа HTML, в который вставлен наш сценарий.

Листинг 15.4. Прерывание выполнения операций цикла


1:    <HTML>
2:    <HEAD>
3:    <TITLE>Пример использования цикла</TITLE>
4:    </HEAD>
5:    <BODY>
6:    <H1>Пример использования цикла</H1>
7:    <P>Введите несколько имен, они будут 
8:    отображены в виде упорядоченного списка.</P>
9:    <SCRIPT LANGUAGE="JavaScript">
10:   names = new Array();
11:   i = 0;
12:   do {
13:       next = prompt("Введите следующее имя");
14:       if (next > " ") names[i] = next;
15:       i = i + 1;
16:   }
17:   while (next > " ");
18:   document.write("<H2>" + (names.length) + " введенных имени.</H2>");
19:   document.write("<OL>");
20:   for (i in names) {
21:       document.write("<LI>" + names[i] + "<BR>");
22:   }
23:   document.write("</OL>");
24:   </SCRIPT>
25:   </BODY>
26:   </HTML>
                   

Если загрузить этот документ в браузер, то на экране появится запрос на введение имени. Введите все необходимые имена, а затем щелкните на кнопке Cancel.

nextn.bmp (246 bytes)

home.gif (161 bytes)

next.gif (900 bytes)

Сайт управляется системой uCoz