aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/guide/loops_and_iteration/index.html
blob: 231bc70804b9c11bbb37821ab1f4e1aa55500e4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
---
title: Циклы и итерации
slug: Web/JavaScript/Guide/Циклы_и_итерации
tags:
  - for
  - операторы цикла
  - циклы
translation_of: Web/JavaScript/Guide/Loops_and_iteration
---
<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</div>

<p class="summary">Циклы - простой способ сделать какое-то действие несколько раз. Эта глава <a href="/ru/docs/Web/JavaScript/Guide">руководства JavaScript Guide</a> познакомит вас с различными операторами доступными в JavaScript.</p>

<p>Вы можете представить цикл в виде компьютеризированной версии игры, где вы говорите кому-то сделать X шагов в одном направлении, затем Y шагов в другом; для примера, идея игры "Иди 5 шагов на восток" может быть выражена в виде цикла:</p>

<pre class="brush: js">var step;
for (step = 0; step &lt; 5; step++) {
  // Запускается 5 раз, с шагом от 0 до 4.
  console.log('Идём 1 шаг на восток');
}
</pre>

<p>Существует множество различных видов циклов, но все они по сути делают тоже самое: повторяют какое-либо действие несколько раз (не забывайте про нулевой раз повторения, отсчёт в массиве начинается с 0). Различные по строению циклы предлагают разные способы для определения начала и окончания цикла. Для различных задач программирования существуют свои операторы цикла, с помощью которых они решаются намного проще.</p>

<p>Операторы предназначеные для организации циклов в  JavaScript:</p>

<ul>
 <li>{{anch("Цикл_for")}}</li>
 <li>{{anch("Цикл_do...while")}}</li>
 <li>{{anch("Цикл_while")}}</li>
 <li>{{anch("Метка_(label)")}}</li>
 <li>{{anch("break")}}</li>
 <li>{{anch("continue")}}</li>
 <li>{{anch("for...in")}}</li>
 <li>{{anch("for...of")}}</li>
</ul>

<h2 id="Цикл_for">Цикл <code>for</code> </h2>

<p>Цикл <strong><a href="/ru/docs/Web/JavaScript/Reference/Statements/for"><code>for</code> </a> </strong>повторяет действия, пока не произойдёт какое-либо специальное событие завершения цикла. Оператор <code>for</code> в JavaScript аналогичен оператору for в Java и C. Объявление оператора <code>for</code> выглядит следующим образом:</p>

<pre class="syntaxbox">for ([начало]; [условие]; [шаг]) выражения
</pre>

<p>При его выполнении происходит следущее:</p>

<ol>
 <li>Выполняется выражение <code>начало</code>, если оно указано. Это выражение обычно инициализирует один или несколько счётчиков, но синтаксис позволяет выражению быть любой сложности. Также используется для объявления переменных.</li>
 <li>Выполняется <code>условие</code>. Если <code>условие</code> истинно, то выполняются <code>выражения</code>. Если оно ложно, цикл <code>for</code> прерывается. Если же <code>условие</code> полностью пропущено, то оно считается истинным.</li>
 <li>Выполняются <code>выражения</code>. Чтобы выполнить несколько выражений, используются блок-выражение  <code>{ ... }</code>  для группировки выражений.</li>
 <li>Обновляется <code>шаг</code>, если он есть, а затем управление возвращается к шагу 2.</li>
</ol>

<h3 id="Пример"><strong>Пример</strong></h3>

<p>В следующей функции есть цикл <code>for</code>, который считает количество выбранных жанров в списке прокрутки (элемент {{HTMLElement("select")}}, который позволяет выбрать несколько элементов). Цикл <code>for</code> объявляет переменную <code>i</code> и задаёт ей значение 0. Также он проверяет, что <code>i</code> меньше количества элементов в элементе <code>&lt;select&gt;</code>, выполняет оператор <code>if</code> и увеличивает <code>i</code> на один после каждого прохода цикла.</p>

<pre class="brush: html">&lt;form name="selectForm"&gt;
  &lt;p&gt;
    &lt;label for="musicTypes"&gt;Выберите некоторые жанры музыки, а затем нажмите на кнопку ниже:&lt;/label&gt;
    &lt;select id="musicTypes" name="musicTypes" multiple="multiple"&gt;
      &lt;option selected="selected"&gt;R&amp;B&lt;/option&gt;
      &lt;option&gt;Jazz&lt;/option&gt;
      &lt;option&gt;Blues&lt;/option&gt;
      &lt;option&gt;New Age&lt;/option&gt;
      &lt;option&gt;Classical&lt;/option&gt;
      &lt;option&gt;Opera&lt;/option&gt;
    &lt;/select&gt;
  &lt;/p&gt;
  &lt;p&gt;&lt;input id="btn" type="button" value="Как много выбрано?" /&gt;&lt;/p&gt;
&lt;/form&gt;

&lt;script&gt;
function howMany(selectObject) {
  var numberSelected = 0;
  for (var i = 0; i &lt; selectObject.options.length; i++) {
    if (selectObject.options[i].selected) {
      numberSelected++;
    }
  }
  return numberSelected;
}

var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
  alert('Выбрано элементов: ' + howMany(document.selectForm.musicTypes))
});
&lt;/script&gt;

</pre>

<h2 id="Цикл_do...while">Цикл <code>do...while</code> </h2>

<p>Цикл <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a></code> повторяется пока заданное условие истинно. Оператор <code>do...while</code> имеет вид:</p>

<pre class="syntaxbox">do
  выражения
while (условие);
</pre>

<p><code>выражения</code> выполняются пока <code>условие</code> истинно. Чтобы использовать несколько выражений, используйте блок-выражение  <code>{ ... }</code>, чтобы сгруппировать их. Если <code>условие</code> истинно, <code>выражения</code> выполнятся снова. В конце каждого прохода <code>условие</code> проверяется. Если <code>условие</code> ложно, выполнение приостанавливается и управление передаётся выражению после <code>do...while</code>.</p>

<h3 id="Пример_2"><strong>Пример</strong></h3>

<p>В следующем примере, цикл <code>do</code> выполнится минимум 1 раз и запускается снова, пока <code>i</code> меньше 5.</p>

<pre class="brush: js">do {
  i += 1;
  console.log(i);
} while (i &lt; 5);</pre>

<h2 id="Цикл_while">Цикл <code>while</code></h2>

<p>Цикл <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/while">while</a></code> выполняет выражения пока условие истинно. Выглядит он так:</p>

<pre class="syntaxbox">while (условие)
  выражения
</pre>

<p>Если <code>условие</code> становится ложным, выражения в цикле перестают выполняться и управление переходит к выражению после цикла.</p>

<p><code>Условие</code> проверяется на истинность до того, как выполняются <code>выражения</code> в цикле. Если <code>условие</code> истинно, выполняются <code>выражения</code>, а затем условие проверяется снова. Если <code>условие</code> ложно, выполнение приостанавливается и управление переходит к выражению после <code>while</code>.</p>

<p>Чтобы использовать несколько выражений, используйте блок выражение <code>{ ... }</code>, чтобы сгруппировать их.</p>

<h3 id="Пример_1"><strong>Пример 1</strong></h3>

<p>Следующий цикл <code>while</code> работает, пока <code>n</code> меньше трёх:</p>

<pre class="brush: js">var n = 0;
var x = 0;
while (n &lt; 3) {
  n++;
  x += n;
}
</pre>

<p>С каждой итерацией, цикл увеличивает <code>n</code> и добавляет это значение к <code>x</code>. Поэтому, <code>x</code> и <code>n</code> получают следующие значения:</p>

<ul>
 <li>После первого прохода: <code>n</code> = 1 и <code>x</code> = 1</li>
 <li>После второго: <code>n</code> = 2 и <code>x</code> = 3</li>
 <li>После третьего прохода: <code>n</code> = 3 и <code>x</code> = 6</li>
</ul>

<p>После третьего прохода, условие <code>n &lt; 3</code> становится ложным, поэтому цикл прерывается.</p>

<h3 id="Пример_2_2"><strong>Пример 2</strong></h3>

<p>Избегайте бесконечных циклов. Убедитесь, что условие цикла в итоге станет ложным; иначе, цикл никогда не прервётся. Выражения в следующем цикле <code>while</code> будут выполняться вечно, т.к. условие никогда не станет ложным:</p>

<pre class="brush: js">while (true) {
  console.log("Hello, world");
}</pre>

<h2 id="Метка_(label)">Метка (label)</h2>

<p><a href="/ru/docs/Web/JavaScript/Reference/Statements/label">Метка</a> представляет собой оператор с индентификатором, который позволяет вам ссылаться на какое-то место в вашей программе. Например, вы можете использовать метку, чтобы обозначить цикл, а затем использовать операторы <code>break</code> или <code>continue</code>, чтобы указать, должна ли программа прерывать цикл или продолжать его выполнение.</p>

<p>Синтаксис метки следующий:</p>

<pre class="syntaxbox">метка :
   оператор
</pre>

<p>Значение <em>метки</em> может быть любым корректным JavaScript индентификатором, не являющимся зарезервированным словом. <code><em>Оператор</em></code><em>, </em>указанный вами после метки может быть любым выражением.</p>

<h3 id="Пример_3"><strong>Пример</strong></h3>

<p>В этом примере, метка <code>markLoop</code> обозначает цикл <code>while</code>.</p>

<pre class="brush: js">markLoop:
while (theMark == true) {
   doSomething();
}</pre>

<h2 id="break"><code>break</code></h2>

<p>Используйте оператор <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/break">break</a></code>, чтобы прерывать цикл, переключать управление или в сочетании с оператором метка.</p>

<ul>
 <li>Когда вы используете <code>break</code> без метки, он прерывает циклы <code>while</code>, <code>do-while</code> и <code>for</code> или сразу переключает управление к следующему выражению.</li>
 <li>Когда вы используете <code>break</code> с меткой, он прерывает специально отмеченное выражение.</li>
</ul>

<p>Синтаксис оператора может быть таким:</p>

<ol>
 <li><code>break;</code></li>
 <li><code>break <em>Метка</em>;</code></li>
</ol>

<p>Первая форма синтаксиса прерывает цикл совсем или переключает управление; вторая прерывает специально обозначенное выражение.</p>

<h3 id="Пример_1_2"><strong>Пример</strong> <strong>1</strong></h3>

<p>Следующий пример проходит по элементам в массиве, пока не найдёт элемент, чьё значение - <code>theValue</code>:</p>

<pre class="brush: js">for (i = 0; i &lt; a.length; i++) {
  if (a[i] == theValue) {
    break;
  }
}</pre>

<h3 id="Пример_2_Прерывание_метки"><strong>Пример 2: Прерывание метки</strong></h3>

<pre class="brush: js">var x = 0;
var z = 0
labelCancelLoops: while (true) {
  console.log("Внешний цикл: " + x);
  x += 1;
  z = 1;
  while (true) {
    console.log("Внутренний цикл: " + z);
    z += 1;
    if (z === 10 &amp;&amp; x === 10) {
      break labelCancelLoops;
    } else if (z === 10) {
      break;
    }
  }
}
</pre>

<h2 id="continue"><code>continue</code></h2>

<p>Оператор <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/continue">continue</a></code> используется, чтобы шагнуть на шаг вперёд в циклах <code>while</code>, <code>do-while</code>, <code>for</code> или перейти к метке.</p>

<ul>
 <li>Когда вы используете <code>continue</code> без метки, он прерывает текущую итерацию циклов <code>while</code>, <code>do-while</code> и <code>for</code> и продолжает выполнение цикла со следующей итерации. В отличие от <code>break</code>, <code>continue</code> не прерывает выполнение цикла полностью. В цикле <code>while </code>он прыгает к условию. А в <code>for</code> увеличивает <code>шаг</code>.</li>
 <li>Когда вы используете <code>continue</code> с меткой, он применяется к циклу с этой меткой.</li>
</ul>

<p>Синтаксис <code>continue</code> может выглядеть так:</p>

<ol>
 <li><code>continue;</code></li>
 <li><code>continue <em>Метка</em></code><em><code>;</code></em></li>
</ol>

<h3 id="Пример_1_3"><strong>Пример 1</strong></h3>

<p>Следующий пример показывает цикл <code>while</code> с оператором <code>continue</code>, который срабатывает, когда значение <code>i</code> равно 3. Таким образом, <code>n</code> получает значения 1, 3, 7 и 12.</p>

<pre class="brush: js">var i = 0;
var n = 0;
while (i &lt; 5) {
  i++;
  if (i == 3) {
    continue;
  }
  n += i;
}
</pre>

<h3 id="Пример_2_3"><strong>Пример 2</strong></h3>

<p>Выражение, отмеченное <em><code>checkiandj</code></em> содержит выражение отмеченное <em><code>checkj</code></em>. При встрече с <code>continue</code>, программа прерывает текущую итерацию <em><code>checkj</code></em> и начинает следующую итерацию. Каждый раз при встрече с <code>continue</code>, <em><code>checkj</code></em> переходит на следующую итерацию, пока условие возвращает <code>false</code>. Когда возвращается <code>false</code>, после вычисления остатка от деления <em><code>checkiandj</code></em><em><code>checkiandj</code></em> переходит на следующую итерацию, пока его условие возвращает <code>false</code>. Когда возвращается <code>false</code>, программа продолжает выполнение с выражения после <em><code>checkiandj</code></em>.</p>

<p>Если у <code>continue</code> проставлена метка <em><code>checkiandj</code></em>, программа может продолжиться с начала метки <em><code>checkiandj</code></em>.</p>

<pre class="brush: js">checkiandj:
  while (i &lt; 4) {
    console.log(i);
    i += 1;
    checkj:
      while (j &gt; 4) {
        console.log(j);
        j -= 1;
        if ((j % 2) != 0) {
          continue checkj;
        }
        console.log(j + " чётное.");
      }
      console.log("i = " + i);
      console.log("j = " + j);
  }</pre>

<h2 id="for...in"><code>for...in</code> </h2>

<p>Оператор <a href="/ru/docs/Web/JavaScript/Reference/Statements/for...in"><code>for...in</code></a> проходит по всем перечислимым свойствам объекта. JavaScript выполнит указанные выражения для каждого отдельного свойства. Цикл <code>for...in</code> выглядит так:</p>

<pre class="syntaxbox">for (variable in object) {
  выражения
}
</pre>

<h3 id="Пример_4"><strong>Пример</strong></h3>

<p>Следующая функция берёт своим аргументом объект и его имя. Затем проходит по всем свойствам объекта и возвращает строку, которая содержит имена свойств и их значения.</p>

<pre class="brush: js">function dump_props(obj, obj_name) {
  var result = "";
  for (var i in obj) {
    result += obj_name + "." + i + " = " + obj[i] + "&lt;br&gt;";
  }
  result += "&lt;hr&gt;";
  return result;
}
</pre>

<p>Для объекта <code>car</code> со свойствами <code>make</code> и <code>model</code>, <font face="Consolas, Liberation Mono, Courier, monospace"><em>результатом </em>будет</font>:</p>

<pre class="brush: js">car.make = Ford
car.model = Mustang
</pre>

<h3 id="Пример_№2">Пример №2</h3>

<p>Также, по ключу можно выводить значение:</p>

<pre>let obj = {model: 'AUDI A8', year: '2019', color: 'brown'}

for (key in obj) {
  console.log(`${key} = ${obj[key]}`);
}
// model = AUDI A8
// year = 2019
// color = brown</pre>

<h3 id="Массивы"><strong>Массивы</strong></h3>

<p>Хотя, очень заманчиво использовать <strong>for...in</strong> как способ пройтись по всем элементам {{jsxref("Array")}}, этот оператор возвращает имя свойств определённых пользователем помимо числовых индексов. Таким образом лучше использовать стандартный <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/for">for</a></code> для числовых индексов при взаимодействии с массивами, поскольку оператор <strong>for...in</strong> проходит по определённым пользователем свойствам в дополнение к элементам массива, если вы изменяете массив, например, добавляете свойства и методы.</p>

<h3 id="Пример_5">Пример</h3>

<pre>let arr = ['AUDI A8', '2019', 'brown'];
arr.cost = '$100.000';

for (key in arr) {
  console.log(`${key} = ${arr[key]}`);
}

// 0 = AUDI A8
// 1 = 2019
// 2 = brown
// cost = $100.000
</pre>

<h2 id="for...of"><code>for...of</code></h2>

<p>Оператор <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/for...of">for...of</a></code> создаёт цикл, проходящий по <a href="/ru/docs/Web/JavaScript/Guide/iterable">перечислимым объектам</a> (включая {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, объект <a href="/ru/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a> и так далее), вызывая на каждой итерации функцию с выражениями, которые надо выполнить для получения значения каждого отдельного свойства.</p>

<pre class="syntaxbox">for (<em>variable</em> of <em>object</em>) {
  <em>выражения
</em>}</pre>

<p>Следующий пример показывает разницу между циклами <code>for...of</code> и <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/for...in" title="ru/docs/JavaScript/Reference/Statements/for...in">for...in</a></code>. Тогда как <code>for...in</code> проходит по именам свойств, <code>for...of</code> проходит по значениям свойств:</p>

<pre class="brush:js">let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
   console.log(i); // выводит "0", "1", "2", "foo"
}

for (let i of arr) {
   console.log(i); // выводит "3", "5", "7"
}
</pre>

<p>{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</p>