Decoded: Destructuring, the Spread Operator & Rest Parameters

Decoded: Destructuring, the Spread Operator & Rest Parameters

The year is 2015. JavaScript developers everywhere cower in darkness, coding by candlelight. Hope was all but lost when the whisper came, a rumour of an update that would bring light to the world. They called it...

ES6

Jokes aside, the introduction of ES6 brought a lot of great new features to JavaScript. In this article, I am going to unpack, or destructure (that joke will make sense later), three of those features:

  1. Destructuring
  2. The spread operator
  3. Rest parameters

Before we get into it, this article is not necessarily intended to be read in one sitting. To make the most of this article, I recommend using it as a reference. Make sure you take a rest between sittings, so you don't spread yourself too thin...

Sorry.

So, without further ado, let's jump in to our first topic.

Destructuring

Destructuring is a way to unpack information from arrays or objects, and concisely assign that information to one or more variables. In the aforementioned dark days of JavaScript, if you wanted to assign part of an array or object to variables, you would have to use bracket or dot notation respectively (see fig 1).

Fig 1. fig 1.png

While this method of assignment works, it is far from efficient. For example, if we wanted to assign each of the values from the array above to its own variable, that would take seven lines of code alone.

We want to make our code more compact, easier to read. This is where destructuring comes in. It allows us to assign all these values to variables using only one line of code.

Let's take a look at destructuring arrays first (fig 2):

Fig 2. fig 2.png

As you can see, the syntax for destructuring is slightly different to regular assignment.

Firstly, we begin by naming all of the variables we wish to create (in this case: bashful, doc and dopey) in an array on the left side of the assignment. Then, we tell our array of variable names where they should get their values from (in this case, the 'arr' array) on the right side of the assignment.

Or more simply put: let [variable names separated by commas] = name of array to take values from;

Each variable we create in our assignment array corresponds to the value in the same position of the array on the right side of the assignment. Here's a more detailed example (fig 3):

Fig 3. fig 3.png

In our assignment array, bashful is the first variable we created (position 0), so that will copy the first value (position 0) of the array we have assigned it to ('arr').

It is worth noting here, that we don't have to give our variables the same name as the value they are assigned to, if I changed [bashful, doc, dopey] to [a, b, c] in our assignment array it would work exactly the same (although it would not be as clear). It is the positions of the variables and values that are important.

Okay, but what if I only wanted to get the fourth and sixth value from 'arr'?

Great question. And the answer is simple.

We skip the earlier values using commas.

Fig 4. fig 4.png

If you look closely at our assignment array, you can see we have left positions 0, 1, 2 and 4 empty - defining only positions 3 and 5. This means that our variables will only take their values from positions 3 and 5 of the 'arr' array ('Grumpy' and 'Sleepy' respectively).

But, this only works for arrays, what about objects?

It works (almost) exactly the same for objects. There is one small difference.

When we want to create our variables, and assign them to values in an array, we use the array syntax ([ ]) to contain them. When creating variables and assigning them to values within an object, we have to use object syntax ({ }) to contain them. See below (fig 5):

Fig 5. fig 5.png

And that's it! A (very basic) introduction to destructuring in JavaScript! Now, before we move on to the next topic...

A (completely optional) quiz!

quiz 1.png

In the snippet above, what would be displayed in the console? (answer below).

Okay, let's move on.

The Spread Operator

The spread operator allows us to assign all the values of an array or object by using the spread operator syntax (...).

We can use this in conjunction with destructuring. Let's return to our seven dwarfs example. This time, however, I am going to use the spread syntax to assign all of the values in the array to a variable using the spread operator and log them to the console (fig 6).

Fig 6. fig 6.png

There are a few different uses cases for the spread operator, such as...

Copying arrays/objects

We can use the spread operator to quickly copy an array in its entirety (fig 7 - note this time we're not using destructuring).

Fig 7. fig 7.png

Adding new items to arrays/objects

Now that we have copied our original array, we can alter the new array, while leaving the original array intact (fig 8).

Fig 8. fig 8.png

It is worth noting that when we add items to an array/object, we can either add them to the beginning or end (or both). 'Arr3' gives us an example of adding a value to the beginning and end of the array. It works like this:

const arr3 = ['Scary', [all of the items in 'arr'], 'Plucky'];

Concatenating arrays/objects

We can also use the spread syntax to concatenate (join) two or more arrays/objects together. For this example, let's join our original array, and a new array (fig 9):

Fig 9. fig 9.png

When we concatenate two arrays like this, this is how the spread operator works:

const dwarfs = [all of arr1, all of arr2]

Before we move on to the final use of the spread operator covered in this article, it is worth noting that using the spread operator when concatenating objects can cause some problems - see the example below (fig 10):

Fig 10. fig 10.png

Even though we concatenated the two objects together, it is only showing the values from 'object2'.

This is because these two objects have the same keys (title, released, dwarfs) - when this happens, these keys are assigned the values that were most recently defined (in this case, 'object2').

If the two objects had different keys, all of the keys would be combined into one object (fig 11):

Fig 11. fig 11.png

This time, we have the unique keys from both objects combined in a new object - note that the 'dwarfs' key is present in both objects, so it takes it value from the most recently defined object ('object2').

Now, for the final spread operator use.

Passing elements of an array to a function as arguments

This section requires some knowledge of functions

Whenever we create a function, we can pass that function arguments, which we can then manipulate in a variety of ways. Let's say we wanted to make a simple array that adds three numbers together, like this (fig 12):

Fig 12. fig 12.png

Instead of typing out the numbers directly when calling the function, we can tell it to take the values from an array by using the spread operator (fig 13):

Fig 13. fig 13.png

However, this only works if the amount of elements in the array is the same as the amount of arguments defined in the function.

The array and function arguments in fig 13 are the same length (2, 4, 6 and x, y, z). If we added another number to the array, the output would remain the same because the function only takes three elements.

And that is the basics of the spread operator!

It's time for round two of our (completely optional) quiz!

What would the following code output to the console? (answers below):

quiz 2.png

Now, for our final topic, rest parameters!

Rest Parameters

In the last example of the previous section (fig 13) we saw how we can use the spread operator to pass the elements of an array to a function as arguments, provided that the amount of array elements and defined function arguments are the same.

But what if we want to create a function with a flexible amount of arguments?

We use rest parameters.

Rest parameters use the same syntax as the spread operator (...), but this time we use this syntax before the function's argument. This allows us to call a function with as many arguments as we'd like (fig 14)!

Fig 14. fig 14.png

You can use rest parameters in conjunction with other arguments, but, you can only use one rest parameter per function, and the rest parameter must be the last function argument (fig 15).

Fig 15. fig 15.png

Before we are finished, there is one final thing...

The final round of the (completely optional) quiz!

What would the following code output to the console?

quiz 3.png

Conclusion

So there we have it! These three relatively simple, yet powerful, additions to JavaScript come in handy in many situations. Now, go and code!

Quiz answers:

#1: 4

#2: [1, 3, 5, 7, 2, 4, 6]

#3: Uncaught SyntaxError: Rest parameter must be last formal parameter

Links

  1. Destructuring - MDN
  2. Spread Operator - MDN
  3. '...spread operator and rest operator - Beau teaches JavaScript'- freeCodeCamp
  4. Rest Parameters - MDN
  5. Rest Parameters and Spread Syntax - Javascript.info