wp-content/uploads/2016/01/PBS_Logo.png

At this stage we’ve learned about three of the key components common to just about every programming language, and how they’re implemented in JavaScript – variables, operators, and branching. Now it’s time to add two more – arrays, and loops.

Arrays store a list of related data in a single variable, and loops allow us to apply the same action over and over again. To process an arbitrarily long array, you need some kind of iteration, and loops are the simplest way of achieving that.

Our Playground

For this instalment we’ll be using our JavaScript playground again. You can download the code for the playground here, or, you can use the online version at www.bartb.ie/pbsdemos/pbs-JavaScriptPlayground/.

Arrays – The Basics

You can think of an array as a single row of old-fashioned pigeon holes that are numbered from zero up. You can put a value in box 0, and another in box 1, and another in box 2, and so on and so forth.

Because JavaScript is an untyped language, you can mix and match data types within a single array. If you’re coming to JavaScript from a strongly typed language like C or Java, this will take some getting used to.

In JavaScript, you create an array of values like this:

The above code creates an array containing three values, element 0 contains the string 'a string', element 1 contains the number 42, and element 2 contains the boolean true.

We can access the values stored in these array elements like so:

We refer to the number inside the square brackets as an index. So, we say that in JavaScript, arrays are indexed from zero up. We also talk about the element at index 0, or the element at index 1, etc..

You can add more values into an array after it has been created by simply assigning a value to the desired array index. Note that in JavaScript, arrays can have gaps.

You don’t have to add any values into an array as you create it – you can create a completely empty array like so:

For those of you coming to JavaScript from strongly typed languages, you’ll be happy to know that JavaScript arrays shrink and grow as needed – you don’t have to declare their size as you create them.

Arrays have a length property which you can assess by appending .length to the array name. Because array indexes start at zero, the length is one greater than the highest defined index. Note that that is exactly how the length is calculated, so an array with just one defined element at index 100 has a length of 101. This concept is demonstrated below:

Back in the first instalment, I mentioned that in JavaScript, variables hold either a literal value (number, string, or boolean), or, a reference to an object. We’ve not looked at objects in any kind of detail yet, and we’re not going for some time yet, but, I do want to flag the fact that in JavaScript, arrays are implemented as objects. This will become important later on in the series.

Loops

Loops allow a block of code to be repeated until a given condition is met. JavaScript supports a number of looping constructs, but we’re just going to focus on the two most common ones in this instalment – the while and for loops.

while Loops

We’ll start with the most generic kind of loop – the while loop. A while loop takes the following form:

The condition is checked, if it evaluates to false, execution jumps beyond the loop, if it evaluates to true, the statement gets executed, then the loop repeats, checking the condition again.

As with if statements, the spec talks about a statement, but, anywhere you can have a statement, you can have a code block, and, just like with if statements, I strongly suggest you get into the habit of always using a code block with your while loops. This is how I suggest you always write your while loops:

As a simple example, let’s use a while loop to total all the elements in an array.

This is a very common code pattern – declare a counter before the loop, increment the counter at the end of the loop, and keep going until some number is reached. This code pattern is so common in fact, that a new looping construct was developed to make the code cleaner – the for loop.

for Loops

for loops were designed to make iterating over a range of numbers easier, and to make such code more easily readable. There is nothing you can do with a for loop that you can’t do with a while loop.

The for loop takes the following form:

Again, you should get into the habit of a using a code block for for loops, so I suggest you always use the following form:

The initialisation_statement gets executed once, and once only, when the loop initiates, then the condition is checked, if it evaluates to false, then execution jumps past the loop, if it evaluates to true, the looped_statement is executed, then the increment_statement, and then we jump back to checking the condition.

If we re-write the above while loop as a for loop you’ll see how much easier it becomes to read

It’s much easier to see that this loop iterates over values of i between zero and the length of the array, because everything relating to the variable being iterated is together on the same line.

You don’t have to call your iteration variable i, but most people do – it’s a convention that even transcends programming languages.

The counter doesn’t have to start at zero, and the updating of the counter doesn’t have to be a simple increment. The following example prints out all odd factors of 13 that are less than 1000 in reverse order:

Watch out for Infinite Loops

When looping in any way, be careful that the loop will always end, otherwise you have what is called an infinite loop, and your script will never get beyond that line of code. It will be doomed to repeat itself for ever! Some browsers will eventually detect that a script has been running for an abnormally long time, and offer to kill it, but others won’t. Your only choice then will be to close the tab/window and start over!

If you’d like to intentionally create an infinite loop, just to see what happens, the following will do it:

You’re very unlikely to do something like the above example by accident, but you could easily make a simple mistake like the one below:

Why is this an infinite loop? We forgot to increment i at the bottom of the loop, so, i will remain zero for ever, and the loop will never end.

Another common mistake is to try loop through an array backwards, but type i++ out of habit, instead of i--:

Since i will keep getting bigger, and the loop will only terminate when i becomes less than zero, it will never end.

Checking if a Variable Contains a Reference to an Array

To check if a variable contains an array reference or not, we need to check if it is an object with the Array prototype (for now, this is technobabble, but it will make sense a few instalments from now). We can do this with the instanceof operator. We’ll revisit this operator later in the series, so for now I’ll just say that the following only evaluates to true when x contains a reference to an array: x instaceof Array.

The truthiness of Arrays

As we learned in the previous instalment, all variables can be collapsed to true or false when needed. For example, we know that all numbers other than zero evaluate to true, and zero to false. All array references evaluate to true, even references to empty arrays.

Worked Example 1 – Product of Inputs

Our first worked example will multiply together the contents of all the non-empty inputs in the playground.

The playground defines a function pbs.inputs(), which returns an array of values from all the non-empty inputs in the interface. This array can be anywhere from zero to three long, depending on how many inputs are left empty.

Worked Example 2 – Print all Multiplication Tables Up to the N-Times Tables

What we’d like to do is print out the multiplication tables for all numbers between 1 and a given number.

Let’s start by writing the code to print the table for any given number:

Now, we can add a second loop around the first loop to go from 1 up to n:

Conclusions

We’re now well on the way to learning about the most important building blocks that are common to all languages. We’ve learned about variables, operators, branching, arrays, and looping. Next on the agenda is functions – named chunks of re-usable code.