Understanding Loops
Loops allow you to run the same code block multiple times until a desired result is reached. They are a kind of short hand, so that you don’t have to write the same code block over and over again. With a loop, you’re basically saying: when this condition is true, do this thing over and over again until the condition is not true. Here’s a diagram to help illustrate what we mean:
There are several common loop statements that we’ll look at, including the while
loop, the for
loop and the do-while
loop.
The best way to get a handle on this is to look at some examples, so stick with us if this feels a little abstract right now.
while
loop
The first loop we will look at is a while
loop. Let’s start out by breaking down the basic syntax of a while
statement.
while(condition){ //code block to be executed }
Just like in the diagram above, we’ll start by evaluating the condition
. The condition
is a boolean statement, so it will either be true
or false
. If the statement is true
, the code in the body (the bit between the two curly braces) will be executed; if the statement is false
the loop terminates and the code in the body isn’t executed. The loop will repeat (or iterate) over and over again until the condition is false. At that point, the loop will terminate, and you’ll move on to the next bit of code.
Here’s an example with some code:
var loopArray = []; var b = 0; while(b < 5) { loopArray.push(b); b++; }
This is telling us that we start with an empty array called loopArray
and a variable b
that has the value of 0
. The condition
in the while
loop asks if b
is less than 5
. If that’s true, we will execute the body of the loop, which tells us to push the current value of b
into the array (loopArray.push(b)
). Then, the value of b
will be incremented (b++
).1
This is where things get… loopy. We will continue to execute that code, as long as the condition returns a value of true
, or, in other words, as long as b
is less than 5
.
Once b
equals 5
, the loop will terminate and we will move on to whatever bit of code is next. When the while
loop is complete, loopArray
will be [0, 1, 2, 3, 4]
.
It can some times be a bit tricky to visualize what’s happening in a loop so you might find it helpful to draw a quick chart. The idea here is that you’ll start with three columns, one for the array, the variable value, and the condition statement. Fill it in with what we know about the loop:
What is in the loopArray? | What is the value of the variable? | State of the Condition |
loopArray | b | b < 5 |
We start with an empt array: [] | 0 | 0 is less than 5: true! |
On each iteration, you’ll evaluate the condition
in the third column of the chart, then you’ll execute the body by adding a new value to the array in the first column, and then update the value of the variable b
in the middle column. Once finished we can clearly see where the loop terminates and what the array contains when that happens. This might seem a little tedious, but it can actually be a really helpful way to visualize what’s happening inside a loop
statement!
loopArray | b | b < 5 |
[] | 0 | true |
[0] | 1 | true |
[0, 1] | 2 | true |
[0, 1, 2] | 3 | true |
[0, 1, 2, 3] | 4 | true |
[0, 1, 2, 3, 4] | 5 | false |
do... while
loop
This loop is very similar to the the while
loop, but instead of first checking to see if the condition
is met before you execute the code block, you’ll execute the code block first–just the first time–and then check the condition to decide if you should continue to execute the code block. It’s basically saying do the code block first. Here’s an example:
var ourArray = []; var b = 0; do { ourArray.push(b); b++; } while (b < 5);
Let’s break that down. We start off with an empty array called ourArray
and a variable b
that has the value of 0
. The first thing we’re going to do is execute the code block; we’ll push b (which has the value of 0
) into ourArray
and then we will increment it by 1. That means that now b = 1
.
You’ll notice that we are always going to execute the code block– at least once– with a do... while
loop. By executing the code block, our array has been updated and the value for b
has changed. This is different than a regular while
loop because with a regular while
loop we will only execute the code block if the condition is true, so it’s possible, if the condition is false, that we will never execute the code block. With a do... while
loop we will always execute it once.
So we start off by executing the code block, but what next? Now, we will evaluate the condition
and ask if it is true
or false
. Remember, our value for b
was updated, so now we’re going to ask if b
(which has a value of 1
) is less than 5
. That is true, so we will execute the code block a second time, and repeat the process of checking the condition
and executing the code block until the condition
is no longer true (when b
has the value of 5
). When we’re finished, ourArray will have [0, 1, 2, 3, 4]
.
Again, the benefit of the do... while
loop is that it gives you the opportunity to execute the code block once before iterating through the loop.
for
loop
A for
loop will feel familiar after you get comfortable with a while
loop. A for
loop will run for a set amount of time and we will pass it three specific instructions. Free Code Camp refers to them as the initialization
, the condition
, and the final-expression
.
The initialization
is basically the set up for the loop; it’s where we might set the variable before the loop starts.
The condition
statement tells you what needs to be true in order for the loop to run. If the condition
is true, the code block will be executed, but it the condition
is false, the loop will be terminated. Just like before, we will revaluate the condition
each time the loop runs.
The final-expression
is usually used to increment or decrement the loop count; you might also see it called an update statement. The final-expression
should be executed at the end of each loop, before you check the condition
statement again.
It’s easiest to understand this with an example. Here’s the syntax of a for
loop:
for (initialization; condition; final-expression){ //code block to be executed }
The initialization
, condition
, and final-expression
are separated by semicolons inside the parenthesis. Aside from that, the for
loop looks similar to the while
loop. Here’s an example with code:
var ourArray = [];
for (var i = 0; i < 3; i++) {
ourArray.push(i);
}
What we’re seeing is an empty array called ourArray
. The initialization
statement in the for
loop introduces the variable i
and sets it to 0
, then the condition
statement reads that i
has to be less than 3
in order for the code block to execute. Since it is true that 0
is less than 3
we will execute the code block, which asks us to push the value of i
into the array. Next the final-expression
asks us to increment i
by 1
. We’ll repeat the for
statement, but this time i
will equal 1
. We will continue to repeat this loop process until i < 3
is no longer true. When we are finished, the array will contain [0, 1, 2]
.
Iterating through an Array
In the examples we have been looking at so far, we have been adding values to empty arrays. But often we’ll want to iterate through the contents of the array– or, in other words, we will want to access the array elements one at a time. The for
loop can help us with that task. Let’s look at an example and then we will unpack it:
var arr = [7, 6, 5, 4, 3]; for (var a = 0; a < arr.length; a++) { console.log(arr[a]); }
This is a very common for
loop so it’s a good idea to know what’s going on inside it.
First we have an array with five values– simple enough! Then, we have our for
loop. Inside, it’s saying that var a = 0
(that’s our initialization
), then we have the condition
that we have to evaluate: a < arr.length
. It’s been a minute since we’ve seen something that looks like arr.length
, so let’s unpack it: arr.length
is the length of the array, or the number of values in it. In other words, the condition is checking if the value for a
is less than the length of the array. We’ve got five values in the array so a
has to be less than 5. So at this point we have to ask ourselves if 0 < 5
, and it is– so then we can execute the code block.
The code block is asking us to look at the contents of the array and log whatever value is indexed at a
. We’ve already established that a = 0
, so we will log the value of the array at index 0
2 so the value that we will log is 7
(the first value in the array).
Next we need to address the final-expression
statement, which asks us to add one to a
. When we do that, we update the value of a
to 1
. Now we’ll go through the condition again (1 < 5
is still true), and execute the code block again (it will return a value of 6
)3 and so on, until the condition is no longer true; in other words, until a
is no longer less than the length of the array. Eventually, we will log the entire array (arr = [7, 6, 5, 4, 3]
) which could be really useful if we weren’t sure what was in the array.
Sometimes you may want to iterate through the loop backwards (i.e. back to front) instead of forwards. This is another common use of loops that you will encounter. Let’s look at an example:
var ourArray = [];
for (var i = 0; i < 3; i++) {
ourArray.push(i);
}
You will see that the initialization statement says that var i = 0
and the looping condition says that i < 3
. We can build out a variable table to help visualize this– here’s what it looks like when finished:
ourArray | i | i < 3 |
[] | 0 | true |
[0] | 1 | true |
[0, 1] | 2 | true |
[0, 1, 2] | 3 | false |
Each row on the table corresponds to an iteration of the loop: so when we start the loop the array is empty, i is 0
, and the conditional statement is true, so we’ll execute the code block by pushing 0
to the array and then incrementing i
by 1
. Now we can start the loop over again, and move through the table.
If you look at the “i
” column on the table you can see that the order that we added our elements into the array was (0, 1, 2
), but if we’re trying to iterate through the loop backwards we will want to add them like this: (2 , 1, 0
) . If we look at the “i
” column in the variable table from last row to first, we recognize the order we actually wanted. So, we can use the same loop body (pushing i
into the array each iteration), except we’ll start with i = 3
and continued through until i = 0
, then we would have achieved our goal! Let’s look at how we can achieve that:
var ourArray = []; for (var i = 3; i = 0; i--) { ourArray.push(i); }
Notice how our initialization condition says that i
starts at 3
instead of 0
, our looping condition says to loop until i
is equal to 0
, and we are decrementing i
instead of incrementing it. This will ultimately give us an array in descending or backward order.
Recursion
Recursion is a slightly advanced programming concept that turns up in our Free Code Camp lessons. It can be a bit frustrating to grasp, but it’s really just a function that calls itself.
You can replace for
loops with a recursive version of the same function, which can make your code easier to read. It’s important to note that the outcome will be the same if you’re using loops or using recursion– it’s really just a more elegant.
To give you a hand with this concept, check out A Quick Intro to Recursion in JavaScript by our friends at Free Code Camp.
Random Number Generators
Next we are going to take a look at a handy JavaScript function that we can use to generate random fractions: Math.random()
.
If you run a value through Math.random()
you will get a random decimal value4 between 0
(inclusive) and 1
(exclusive), meaning that the value you get from Math.random()
might be as low as 0
but will never be as high as 1
.
With a little bit of work you can even use the random number generator function to generate random integers5.
To get a random number greater than 1
, you can multiply the function by an integer6. Here’s what that would look like: Math.random() * 10
.
The result would be a random number with a decimal that could be anything between 0
and just under 10
.7
To convert that number into an integer, we will use the Math.floor
function, which converts the value to an integer by rounding down to the closest integer. Here’s what it would all look like put together: Math.floor(Math.random() * 10)
So if Math.random() * 10
was equal to 8.2
, then Math.floor(Math.random() *10)
would be equal to 8.
Generate a Random Number from a Range
Lastly, we can also generate a random number that falls within a specific range. This might look a little complicated at first, but stick with it! Here’s the formula:
Math.floor(Math.random() * (max - min + 1)) + min
The easiest way to get a handle on this is to see it in action. We’ll use that formula in the body of a function to generate a random number between 2
and 15
.
function randomRange(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min } var randomNum = randomRange(2, 15)
Okay, so here we have a function called randomRange
that has two parameters: a min
and a max
. We want our variable randomNum
to equal the output of randomRange
when we pass the arguments 2
and 15
through the function. This will generate a random number between 2 and 15.
Let’s walk through the rest of the function step by step. First will fill in the formula with our min and max values.
return Math.floor(Math.random() * (15 - 2 + 1)) + 2
We’ll start by solving the inner most parentheses first: (15 - 2 + 1)
is equal to 14
. Math.random
will generate a random decimal– let’s say it gives us .2
. We will multiply that by 14
which gives us 2.8
. Next we’ll use Math.floor
to turn that into an integer by rounding down, so it becomes 2
. Lastly, we will add that value to our minimum (which also happens to be 2
) to complete the function, which gives us 4
. In other words, var randomNum = 4
.
Parsing Strings to Integers
The parseInt()
function allows you to turn a string into a number.8 For example: var b = parseInt("0028")
would give you the number 28
. Here’s another one: var b = parseInt("44")
. This converts the string "44
” to the number 44
.
Why might we want to do this? Remember, we can only preform mathematical operations on numbers; we can’t perform them on strings, even if the string looks like a number.
What would happen if we try to run a string that didn’t “look like” a number through the parseInt()
? It would return NaN
, which stands for “not a number.” So, parseInt("bananas")
would return NaN
.
You’ve actually already seen examples of the parseInt()
function without even realizing it : 5=="5"
is true because Javascript is automatically parsing the string "5"
into the number 5
for you! If you want you can even parse strings which represent numbers in various different bases (beyond base 10) by passing another argument to the parseInt()
function called a radix
, though that’s a bit advanced for what we’re covering here…
The Conditional (Ternary) Operator
There is a special operator in Javascript called the conditional operator – or some times the ternary operator. Do you know what unary means? It means consisting of a single element. Binary? Consisting of two elements. What about ternary? If you guessed consisting of three elements you’re right! The ternary operator takes three elements and provides one result. Here’s the syntax for a ternary operator:
condition ? val1 : val2
It can be helpful to think of the ternary operator as related to the else if
statement, because it’s ultimately doing the same thing: it’s saying if a condition is true return val 1
, else if a condition is false return val 2
.
The condition
of a ternary statement can be any boolean statement (something that returns a boolean value). If this sounds familiar to you, it’s most likely because the ternary operator is just a short way of saying this:
if (condition) return val1; else return val2;
You can actually nest multiple ternary statements together so that if the first condition is false, you’ll evaluate a second condition rather than just returning a value. Here’s what that might look like:
function findGreaterOrEqual(a, b) { return (a === b) ? "a and b are equal" : (a > b) ? "a is greater" : "b is greater"; }
In this example we are asking if a is strictly equal to b. If it is, we return the value “a and b are equal.” If it’s not, we look at a second condition: is a greater than b? If it is, we return “a is greater.” It’s it’s not, we return “b is greater.”
Note: we can have multiple lines of code in the body of a loop statement! Just make sure that each line ends with a semicolon.↩
Remember, we start indexing arrays at zero instead of one, because computers count from zero↩
Again, when we’re indexing arrays, we start counting at zero. So when
a = 1
we’re actually looking for the second value in the array, which is6
.↩Also called a float value↩
Quick math refresher: whole numbers are integers. Numbers with a decimal place are not integers. I know, it’s been a minute.↩
This is called scaling.↩
Why couldn’t it be
10
? Because Math.random generates a decimal value that is less than1
.↩Remember that strings and numbers are two different data types. Strings will always be in quotation marks.↩