jskatas.org Continuously Learn JavaScript. Your Way.

Learning JavaScript Arrays

An array is like a queue where you can have zero, one or many values. The first value can be found at index 0, and others follow. An empty array, like a queue with no one in it, is written in JavaScript as []. The [ and ] are the start and end markers, and items inside are separated by commas. For example, to make an array with the numbers 0 to 3, you write [0, 1, 2, 3].

Let's start to build a queue in JavaScript, using an array. But before we get started, let me set the stage.

Content

  1. How do we work?
  2. Creating an Array
  3. Accessing Items
  4. Using the *.at() Function
  5. Using the *.toReversed() Function
  6. You want more?

How do we work?

This article has one non-negotiable goal.

Test-First

Test-first is an approach often sidelined in software engineering. If you can't define your goal, you can't achieve it, and writing a test is a way to do that. This might feel strange because test-writing isn't common enough, especially when learning programming. But it's a skill that's worth learning, it will when practiced make you not just a better programmer, but also a better thinker and engineer, because it forces you to do the right thing right. If you're not willing to embrace this, this article isn't for you.

First Test

Let's get to work. Below is a small JavaScript code editor. The assert(...) function takes any expression — simply put, some code — in place of the ..., and tells us if the expression is valid. For example, assert(1) will turn the editor green (try it), while assert(false) will cause the editor to complain and the test is red (an expression commonly used whe working with tests).

Let's try. The instructions are given in a given-when-then style, to understand what is to be achieved.

GIVEN an assert function call with ... as parameter
WHEN you pass a truthy parameter (for example true or 1)
THEN the test will be green.
ℹ️ Try other values that makes the test green, maybe 0, 1, "" or something else instead of the ....
ℹ️ Try out if an empty array ([]) will be ok!

assert(...)

You made the test above green and experimented a bit. How does it feel? Instant feedback and a simple goal, isn't that nice?
We are all set, now let's learn something about arrays.

Creating an Array

There are many ways to create an array, let's explore the most used one and some exotic ones.

The Literal - []

In programming languages there are many literals, which shall make using certain programming constructs easier or less code to write, but they also come with a learning curve. One simply has to learn that [ starts an array and ] ends it.
⚠️ This is not the only use of the brackets (that's what they are called) in JavaScript (and many other programming languages), but let's ignore the other uses here.

GIVEN a variable emptyArray
WHEN you assign an empty array to it (using the brackets)
THEN the test will be green.
ℹ️ The lines starting with assert are testing if you fulfill this task, so please do not change them!

const emptyArray = 0;

// Don't change the lines below, just edit code above this line. assert(Array.isArray(emptyArray), 'emptyArray is not an array (yet)'); assert(emptyArray.length === 0, \emptyArray` seems to have ${emptyArray.length} items, not 0 as expected`);

Accessing Items

Above has been quite technical, so let's become a bit more practical. Let's assume we want to program a queue with some people. The queue we are using (the array) only has the ages of the people. For example: [10, 17, 18, 22, 33]. The first person in the queue is 10 years old, the second 18, and so on. As touched on above, the first person in the queue is at index 0 and the second at index 1.

Let's try accessing the first person's age.

GIVEN an array (a queue) with the ages of people, here we use [10, 17, 18, 22, 33]
WHEN we want to read the first person's age
THEN we add the prefix [0] to the array's name, like peoplesAges[0]
ℹ️ Remember to not change the line(s) with the assert on it!

const peoplesAges = [10, 17, 18, 22, 33]; const firstPersonsAge = peoplesAges[____];

// Don't change the lines below, just edit code above this line. assert.equal(firstPersonsAge, 10);

Test is green? Accessing an array's item is done using a numerical index, starting with 0. If that was too easy, try adding all the ages of all the people.

GIVEN an array (a queue) with the ages of people, like above
WHEN we want to sum up all the ages
THEN we read each age by adding the according prefixes, like [0], [1], [2], ... and sum those up
ℹ️ Remember to not change the line(s) with the assert on it!

const peoplesAges = [10, 17, 18, 22, 33]; const sumOfAges = peoplesAges[0] + peoplesAges[1];

// Don't change the lines below, just edit code above this line. assert.equal(sumOfAges, 100);

Indexing the elements via [0], [1], [2], ... is a bit cumbersome. What if the array grows dynamically? So let's try to make it easier. And a bit more generic by letting a counter just look up one after another, for that we use the counter++ notation, which means "increase the counter by one" and we use this new value for reading the item in our queue/array.

GIVEN again, an array of ages, like above
WHEN we want to sum up all ages
THEN we can add up peoplesAges[index++] as often until index has increased to the length of the array
ℹ️ What does index++ do? It increases index in place, and we can also use it as index for the array.
ℹ️ Remember to not change the line(s) with the assert on it!

const peoplesAges = [10, 17, 18, 22, 33]; let counter = 0; const sumOfAges = peoplesAges[counter++] + peoplesAges[counter++] + peoplesAges[counter++];

// Don't change the lines below, just edit code above this line. assert.equal(sumOfAges, 100);

Using the *.at() Function

Accessing items in an array using the brackets ([ and ]) is the standard and most often used way. Since 2019 there is a new function array.at() to access items in an array. It is a bit more flexible than the brackets we used above. Let's try it out instead of the brackets.
One aspect of arrays that we didn't cover yet: array items can be of various types, they can be any type of value, even other arrays. We will use strings, as the names of people in our queue, like so ['Fatima', 'Raj', ...], and we will access the names of the people as we accessed the ages above but this time we use the at() function.

GIVEN an array (a queue) with the names of people
WHEN we want to read the second person's name
THEN we use the names.at(1) function.
ℹ️ Try to play with the parameter, for example 0, null or even "some string".

const names = ['Fatima', 'Raj', 'Amina', 'Carlos', 'Mei']; const firstPersonsName = names.at(0);

// Don't change the lines below, just edit code above this line. assert.equal(firstPersonsName, 'Raj');

Let's try to apply the at() function on the array of ages we worked on before. Instead of accessing the ages with the brackets, we will use the at() function.

GIVEN an array with the ages of people, like above
WHEN we want to sum up all ages using the at() function
THEN this works like accessing the array using the brackets.

const peoplesAges = [10, 17, 18, 22, 33]; const sumOfAges = peoplesAges.at(0) + peoplesAges.at(1) + peoplesAges.at(2);

// Don't change the lines below, just edit code above this line. assert.equal(sumOfAges, 100);

Why was at() introduced, one might ask. It was introduced quite late, 22 years after JavaScript was born. There must have been a need, right? JavaScript takes a lot of inspiration from e.g. Python and that was one thing that I believe came from it, because in Python accessing arrays is way more flexible, than in JavaScript. Let's see what else the at() function offers.

A nice feature of the at() function, which would have broken JavaScript if done with brackets, is that it can also be used to access items from the end of the array. For example, names.at(-1) will return the last item in the array, and names.at(-2) the second last, and so on.

GIVEN an array (a queue) with the names of people, as above
WHEN we want to read the person's names in reverse order
THEN we call names.at(-1), names.at(-2), ... functions.

const names = ['Fatima', 'Raj', 'Amina', 'Carlos', 'Mei']; const reverseNames = [names.at(1), names.at(2), names.at(3)];

// Don't change the lines below, just edit code above this line. assert.deepStrictEqual(reverseNames, ['Mei', 'Carlos', 'Amina', 'Raj', 'Fatima'], `Was "${reverseNames.join(',')}" but should be "${['Mei', 'Carlos', 'Amina', 'Raj', 'Fatima'].join(',')}".`);

Good job. If you are wondering if this can be done easier. You are on the right track, and as usual there are many ways to do things in programming.

Using the *.toReversed() Function

Just lately in JavaScript's 14th edition from the year 2023, also called ES2023, a new function array.toReversed() was introduced. What you did above, by accessing every member of the array explicitly from the end towards the beginning, can be done in one go, just reversing the array and returning a new one. Let's try it out.

GIVEN an array (a queue) with the names of people, as above
WHEN we want to get a new array with all the names in reverse order, and use only one function call
THEN we can use array.toReversed() to achieve this.

const names = ['Fatima', 'Raj', 'Amina', 'Carlos', 'Mei']; const reverseNames = names;

// Don't change the lines below, just edit code above this line. assert.deepStrictEqual(reverseNames, ['Mei', 'Carlos', 'Amina', 'Raj', 'Fatima'], `Was "${reverseNames.join(',')}" but should be "${['Mei', 'Carlos', 'Amina', 'Raj', 'Fatima'].join(',')}".`);

You want more?

Thanks a lot for exploring arrays with me so far. If you have comments or any type of feedback, I would love to hear from you either on mastodon or maybe on LinkedIn.