|
| 1 | +# Loops |
| 2 | + |
| 3 | +A loop is a programming construct to perform a repetitive action. Often (but not always) the repetitive action involves accessing or manipulating the individual elements of an array. |
| 4 | + |
| 5 | +We will use the array of month names given below to illustrate the various types of loop constructs available in JavaScript. In the examples we will print out the names of the invidual months using a `console.log` statement. |
| 6 | + |
| 7 | +```js |
| 8 | +const months = [ |
| 9 | + 'January', 'February', 'March', 'April', 'May', 'June', |
| 10 | + 'July', 'August', 'September', 'October', 'November', 'December' |
| 11 | +]; |
| 12 | +``` |
| 13 | + |
| 14 | +## while |
| 15 | + |
| 16 | +The `while` loop is probably the simplest one of the bunch. Its general syntax is: |
| 17 | + |
| 18 | +```js |
| 19 | +while (cond) { |
| 20 | + // statement block to be repeated |
| 21 | +} |
| 22 | +``` |
| 23 | + |
| 24 | +The loop 'body' (i.e., the statement block including the curly braces) is executed while the condition `cond` holds true. In order for this while loop to execute at least once and to finish in finite time two preconditions must be fulfilled: |
| 25 | + |
| 26 | +1. The condition `cond` should initially hold true. |
| 27 | +2. Some code inside the code block must eventually cause the condition to become false. |
| 28 | + |
| 29 | +Applied to our `months` array the while loop would look like this: |
| 30 | + |
| 31 | +```js |
| 32 | +const months = [ |
| 33 | + ... |
| 34 | +]; |
| 35 | + |
| 36 | +let index = 0; |
| 37 | +const len = months.length; // 12 |
| 38 | + |
| 39 | +while (index < len) { |
| 40 | + console.log(months[index]); |
| 41 | + index += 1; |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +In this example the two preconditions mentioned earlier are met: |
| 46 | + |
| 47 | +1. The condition `index < len` initially holds true because `index` is initialized to `0` and we know that `len` is fixed at the value of `12` (hence the use of `const` rather than `let`). |
| 48 | +2. Because the value of `index` is incremented by one each time the loop body is executed there will be a point in time when the loop condition becomes false. This will happen when the value `index` has become `12` and `index < len` no longer holds true. |
| 49 | + |
| 50 | +If precondition 2 is **not** met then your loop will execute forever. This is what is commonly referred to as an _infinite loop_. Your code will appear to 'hang' when this happens, and you will need to somehow terminate the program and fix the problem (e.g., press Ctrl-C when running in Node). |
| 51 | + |
| 52 | +More info on MDN: [while](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while) |
| 53 | + |
| 54 | +## do...while |
| 55 | + |
| 56 | +This is a variation of the while loop discussed above. Its general syntax is: |
| 57 | + |
| 58 | +```js |
| 59 | +do { |
| 60 | + // statement block to be repeated |
| 61 | +} while (cond); |
| 62 | +``` |
| 63 | + |
| 64 | +The do...while loop is executed at least once, because the loop condition is evaluated at the _end_ of the loop rather than at the _beginning_ as is the case with the regular `while` loop. |
| 65 | + |
| 66 | +Applied to our 'months' example the code would look like this: |
| 67 | + |
| 68 | +```js |
| 69 | +const months = [ |
| 70 | + ... |
| 71 | +]; |
| 72 | + |
| 73 | +let index = 0; |
| 74 | +const len = months.length; |
| 75 | + |
| 76 | +do { |
| 77 | + console.log(months[index]); |
| 78 | + index += 1; |
| 79 | +} while (index < len) |
| 80 | +``` |
| 81 | + |
| 82 | +We recommend that you do not use the `do...while` loop, exactly for the reason that the loop body is executed at least once without taking the loop condition into account. It is always possible to rewrite a `do...while` loop into a regular `while` loop that strictly meets the two preconditions mentioned earlier. |
| 83 | + |
| 84 | +More info on MDN: [do...while](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while) |
| 85 | + |
| 86 | +## for |
| 87 | + |
| 88 | +The `for` loop is the most used loop construct that you will come across and that you are likely to use most in your own code. It exists in a number of variations in JavaScript that we will cover one by one below. The syntax of the most generic form is as follows: |
| 89 | + |
| 90 | +```js |
| 91 | +for ([initialization]; [condition]; [final-expression]) { |
| 92 | + // statement block to be repeated |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +Let's first look at an example: |
| 97 | + |
| 98 | +```js |
| 99 | +const months = [ |
| 100 | + ... |
| 101 | +]; |
| 102 | + |
| 103 | +const len = months.length; |
| 104 | + |
| 105 | +for (let index = 0; index < len; index++) { |
| 106 | + console.log(months[index]); |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +The `for` statement combines three parts of the loop construct in a single statement. Those three parts are separated by semicolons and, enclosed within parentheses, directly follow the `for` keyword. |
| 111 | + |
| 112 | +1. The first part is the for loop initialization of a loop 'index' variable, here called `index`. (Often you will see one letter variable names, such as `i` for the loop index.). This part is executed only once. |
| 113 | +2. The second part is the loop condition, and is evaluated for every loop [iteration](http://www.dictionary.com/browse/iteration). The loop body is executed while this condition holds true. Note that this condition is tested at the beginning of the loop (like `while` above) and **not** at the end (like `do...while`). |
| 114 | +3. The last part is where the loop index variable is updated, in this case incremented by one (`index++` is short for `index += 1`, which in itself is short for `index = index + 1`). This update is effectively done at the end of the loop (in the example, after the console.log has been executed). |
| 115 | + |
| 116 | +More info on MDN: [for](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) |
| 117 | + |
| 118 | +## for...of |
| 119 | + |
| 120 | +The `for...of` loop construct is relatively new and very well suited for use with arrays. It was introduced with the ES6 variant of JavaScript. Its general syntax is: |
| 121 | + |
| 122 | +```js |
| 123 | +for (variable of iterable) { |
| 124 | + // statement block to be repeated |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +Here, `iterable` can be a couple of things, but most of the time it is just an array variable. Let's again look at an example. |
| 129 | + |
| 130 | +```js |
| 131 | +const months = [ |
| 132 | + ... |
| 133 | +]; |
| 134 | + |
| 135 | +for (const month of months) { |
| 136 | + console.log(month); |
| 137 | +} |
| 138 | +``` |
| 139 | + |
| 140 | +With this `for` loop variant, the array is considered a collection of elements (you can _iterate_ through a collection: it is 'iterable'). Each time the loop body is executed the loop variable receives the next value of the array (in the example, starting with `'January'` and ending with `'December'`). |
| 141 | + |
| 142 | +This now allows us to write very elegant and short code. No need to mess around with a loop index variable, array lengths etc. If you need to use a `for` loop involving arrays, this will often be your first choice. |
| 143 | + |
| 144 | +More on MDN: [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) |
| 145 | + |
| 146 | +## for..in |
| 147 | + |
| 148 | +This loop variant is for use with JavaScript objects only. It existed before the `for...of` loop variant became available. |
| 149 | + |
| 150 | +We will discuss the `for...in` variant in more detail the part of the curriculum where we deal with Objects. Here, we will suffice to say that the `for...in` loop construct can easily be rewritten as a `for...of` loop, as follows: |
| 151 | + |
| 152 | +```js |
| 153 | +const obj = { |
| 154 | + a: 10, |
| 155 | + b: 'test' |
| 156 | +} |
| 157 | + |
| 158 | +// for...in |
| 159 | +for (const key in obj) { |
| 160 | + console.log(obj[key]) |
| 161 | +} |
| 162 | + |
| 163 | +// equivalent for...of |
| 164 | +for (const key of Object.keys(obj)) { |
| 165 | + console.log(obj[key]) |
| 166 | +} |
| 167 | +``` |
| 168 | + |
| 169 | +More info on MDN: [for...in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in) |
0 commit comments