diff --git a/1-js/02-first-steps/12-while-for/article.md b/1-js/02-first-steps/12-while-for/article.md index e600b8c4b9..992c21af64 100644 --- a/1-js/02-first-steps/12-while-for/article.md +++ b/1-js/02-first-steps/12-while-for/article.md @@ -1,10 +1,10 @@ # Loops: while and for -We often have a need to perform similar actions many times in a row. +We often need to repeat actions. -For example, when we need to output goods from a list one after another. Or just run the same code for each number from 1 to 10. +For example, outputting goods from a list one after another or just running the same code for each number from 1 to 10. -*Loops* are a way to repeat the same part of code multiple times. +*Loops* are a way to repeat the same code multiple times. ## The "while" loop @@ -31,11 +31,11 @@ while (i < 3) { // shows 0, then 1, then 2 A single execution of the loop body is called *an iteration*. The loop in the example above makes three iterations. -If there were no `i++` in the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and for server-side JavaScript we can kill the process. +If `i++` was missing from the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and in server-side JavaScript, we can kill the process. -Any expression or a variable can be a loop condition, not just a comparison. They are evaluated and converted to a boolean by `while`. +Any expression or variable can be a loop condition, not just comparisons: the condition is evaluated and converted to a boolean by `while`. -For instance, the shorter way to write `while (i != 0)` could be `while (i)`: +For instance, a shorter way to write `while (i != 0)` is `while (i)`: ```js run let i = 3; @@ -68,7 +68,7 @@ do { } while (condition); ``` -The loop will first execute the body, then check the condition and, while it's truthy, execute it again and again. +The loop will first execute the body, then check the condition, and, while it's truthy, execute it again and again. For example: @@ -80,11 +80,11 @@ do { } while (i < 3); ``` -This form of syntax is rarely used except when you want the body of the loop to execute **at least once** regardless of the condition being truthy. Usually, the other form is preferred: `while(…) {…}`. +This form of syntax should only be used when you want the body of the loop to execute **at least once** regardless of the condition being truthy. Usually, the other form is preferred: `while(…) {…}`. ## The "for" loop -The `for` loop is the most often used one. +The `for` loop is the most commonly used loop. It looks like this: @@ -102,14 +102,14 @@ for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2 } ``` -Let's examine the `for` statement part by part: +Let's examine the `for` statement part-by-part: | part | | | |-------|----------|----------------------------------------------------------------------------| | begin | `i = 0` | Executes once upon entering the loop. | -| condition | `i < 3`| Checked before every loop iteration, if fails the loop stops. | -| step| `i++` | Executes after the body on each iteration, but before the condition check. | -| body | `alert(i)`| Runs again and again while the condition is truthy | +| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. | +| step| `i++` | Executes after the body on each iteration but before the condition check. | +| body | `alert(i)`| Runs again and again while the condition is truthy. | The general loop algorithm works like this: @@ -121,9 +121,9 @@ Run begin → ... ``` -If you are new to loops, then maybe it would help if you go back to the example and reproduce how it runs step-by-step on a piece of paper. +If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper. -Here's what exactly happens in our case: +Here's exactly what happens in our case: ```js // for (let i = 0; i < 3; i++) alert(i) @@ -140,7 +140,7 @@ if (i < 3) { alert(i); i++ } ``` ````smart header="Inline variable declaration" -Here the "counter" variable `i` is declared right in the loop. That's called an "inline" variable declaration. Such variables are visible only inside the loop. +Here, the "counter" variable `i` is declared right in the loop. This is called an "inline" variable declaration. Such variables are visible only inside the loop. ```js run for (*!*let*/!* i = 0; i < 3; i++) { @@ -149,7 +149,7 @@ for (*!*let*/!* i = 0; i < 3; i++) { alert(i); // error, no such variable ``` -Instead of defining a variable, we can use an existing one: +Instead of defining a variable, we could use an existing one: ```js run let i = 0; @@ -190,9 +190,9 @@ for (; i < 3;) { } ``` -The loop became identical to `while (i < 3)`. +This makes the loop identical to `while (i < 3)`. -We can actually remove everything, thus creating an infinite loop: +We can actually remove everything, creating an infinite loop: ```js for (;;) { @@ -200,15 +200,15 @@ for (;;) { } ``` -Please note that the two `for` semicolons `;` must be present, otherwise it would be a syntax error. +Please note that the two `for` semicolons `;` must be present. Otherwise, there would be a syntax error. ## Breaking the loop -Normally the loop exits when the condition becomes falsy. +Normally, a loop exits when its condition becomes falsy. -But we can force the exit at any moment. There's a special `break` directive for that. +But we can force the exit at any time using the special `break` directive. -For example, the loop below asks the user for a series of numbers, but "breaks" when no number is entered: +For example, the loop below asks the user for a series of numbers, "breaking" when no number is entered: ```js let sum = 0; @@ -227,15 +227,15 @@ while (true) { alert( 'Sum: ' + sum ); ``` -The `break` directive is activated at the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing the control to the first line after the loop. Namely, `alert`. +The `break` directive is activated at the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing control to the first line after the loop. Namely, `alert`. -The combination "infinite loop + `break` as needed" is great for situations when the condition must be checked not in the beginning/end of the loop, but in the middle, or even in several places of the body. +The combination "infinite loop + `break` as needed" is great for situations when a loop's condition must be checked not in the beginning or end of the loop, but in the middle or even in several places of its body. ## Continue to the next iteration [#continue] -The `continue` directive is a "lighter version" of `break`. It doesn't stop the whole loop. Instead it stops the current iteration and forces the loop to start a new one (if the condition allows). +The `continue` directive is a "lighter version" of `break`. It doesn't stop the whole loop. Instead, it stops the current iteration and forces the loop to start a new one (if the condition allows). -We can use it if we're done on the current iteration and would like to move on to the next. +We can use it if we're done with the current iteration and would like to move on to the next one. The loop below uses `continue` to output only odd values: @@ -249,9 +249,9 @@ for (let i = 0; i < 10; i++) { } ``` -For even values of `i` the `continue` directive stops body execution, passing the control to the next iteration of `for` (with the next number). So the `alert` is only called for odd values. +For even values of `i`, the `continue` directive stops executing the body and passes control to the next iteration of `for` (with the next number). So the `alert` is only called for odd values. -````smart header="The directive `continue` helps to decrease nesting level" +````smart header="The `continue` directive helps decrease nesting" A loop that shows odd values could look like this: ```js @@ -264,13 +264,13 @@ for (let i = 0; i < 10; i++) { } ``` -From a technical point of view it's identical to the example above. Surely, we can just wrap the code in the `if` block instead of `continue`. +From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`. -But as a side-effect we got one more nesting level (the `alert` call inside the curly braces). If the code inside `if` is longer than a few lines, that may decrease the overall readability. +But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of`if` is longer than a few lines, that may decrease the overall readability. ```` ````warn header="No `break/continue` to the right side of '?'" -Please note that syntax constructs that are not expressions cannot be used with the ternary operator `?`. In particular, directives such as `break/continue` are disallowed there. +Please note that syntax constructs that are not expressions cannot be used with the ternary operator `?`. In particular, directives such as `break/continue` aren't allowed there. For example, if we take this code: @@ -282,24 +282,24 @@ if (i > 5) { } ``` -...And rewrite it using a question mark: +...and rewrite it using a question mark: ```js no-beautify -(i > 5) ? alert(i) : *!*continue*/!*; // continue not allowed here +(i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here ``` -...Then it stops working. The code like this will give a syntax error: +...it stops working. Code like this will give a syntax error: -That's just another reason not to use a question mark operator `?` instead of `if`. +This is just another reason not to use the question mark operator `?` instead of `if`. ```` ## Labels for break/continue Sometimes we need to break out from multiple nested loops at once. -For example, in the code below we loop over `i` and `j` prompting for coordinates `(i, j)` from `(0,0)` to `(3,3)`: +For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(3,3)`: ```js run no-beautify for (let i = 0; i < 3; i++) { @@ -318,7 +318,7 @@ alert('Done!'); We need a way to stop the process if the user cancels the input. -The ordinary `break` after `input` would only break the inner loop. That's not sufficient. Labels come to the rescue. +The ordinary `break` after `input` would only break the inner loop. That's not sufficient--labels, come to the rescue! A *label* is an identifier with a colon before a loop: ```js @@ -327,9 +327,7 @@ labelName: for (...) { } ``` -The `break ` statement in the loop breaks out to the label. - -Like here: +The `break ` statement in the loop below breaks out to the label: ```js run no-beautify *!*outer:*/!* for (let i = 0; i < 3; i++) { @@ -347,7 +345,7 @@ Like here: alert('Done!'); ``` -In the code above `break outer` looks upwards for the label named `outer` and breaks out of that loop. +In the code above, `break outer` looks upwards for the label named `outer` and breaks out of that loop. So the control goes straight from `(*)` to `alert('Done!')`. @@ -358,10 +356,10 @@ outer: for (let i = 0; i < 3; i++) { ... } ``` -The `continue` directive can also be used with a label. In this case the execution jumps to the next iteration of the labeled loop. +The `continue` directive can also be used with a label. In this case, code execution jumps to the next iteration of the labeled loop. ````warn header="Labels are not a \"goto\"" -Labels do not allow us to jump into an arbitrary place of code. +Labels do not allow us to jump into an arbitrary place in the code. For example, it is impossible to do this: ```js @@ -370,7 +368,7 @@ break label; // jumps to label? No. label: for (...) ``` -The call to a `break/continue` is only possible from inside the loop, and the label must be somewhere upwards from the directive. +A call to `break/continue` is only possible from inside a loop and the label must be somewhere above the directive. ```` ## Summary @@ -383,6 +381,6 @@ We covered 3 types of loops: To make an "infinite" loop, usually the `while(true)` construct is used. Such a loop, just like any other, can be stopped with the `break` directive. -If we don't want to do anything on the current iteration and would like to forward to the next one, the `continue` directive does it. +If we don't want to do anything in the current iteration and would like to forward to the next one, we can use the `continue` directive. -`break/continue` support labels before the loop. A label is the only way for `break/continue` to escape the nesting and go to the outer loop. +`break/continue` support labels before the loop. A label is the only way for `break/continue` to escape a nested loop to go to an outer one.