Unlocking the power of the rest and spread operators in JavaScript

Rest and spread are two powerful JavaScript features introduced in ES6. These are two related features, primarily used with arrays and objects. While both of these features share the same syntax ..., their functions are different. Let's take a look at each of them.

The rest operator

The rest operator allows us to pack elements or properties into an array or object. There are two primary use cases of the rest operator: in array and object destructuring and in a function parameter.

In array and object destructuring

Extracting a portion of an array or object when destructuring is one of the primary use cases of the rest operator.

// Extract a portion of an array
const numbers = [1, 2, 3, 4, 5];

const [first, ...restNumbers] = numbers;

console.log(restNumbers); // [ 2, 3, 4, 5 ]

// Extract a portion of an object
const person = {
  name: 'John',
  age: 30,
  occupation: 'Software developer',
};
const { name, ...restPerson } = person;

console.log(restPerson); // { age: 30, occupation: 'Software developer' }

In the first example, we've destructured the numbers array, creating two variables called first and restNumbers, where first corresponds to the first element in the array, and restNumbers is an array containing the remaining array elements.

In the second example, we've destructured the person object, creating two variables called name and restPerson, where name corresponds to the name property in the object, and restPerson is an object containing the remaining object properties.

Notice that in both cases, we've used the rest operator to extract a portion of the array and object. This feature is particularly useful when we want to remove a few properties from an object.

Two important points regarding the rest operator when used in destructuring: it must be the last variable, and we can create a single variable using it in a destructuring assignment.

If you want to dive deep into array and object destructuring, I have an article on Understanding Array and Object destructuring in JavaScript that provides further insights.

In function parameter

The second use case of the rest operator is in function parameter, as shown in the following example:

function add(...numbers) {
  console.log(numbers); // [ 2, 4, 8 ]
}

add(2, 4, 8);

In this example, we've used the rest operator in the function parameter. By doing so, any number of arguments provided to the add function will be packed into an array, which is a flexible alternative to passing an array directly to the function.

Good to know that there is a difference between getting the arguments via the arguments keyword and using the rest parameter. The arguments keyword provides an array-like object, while the rest parameter creates a real array.

Also, the arrow function doesn't have the arguments keyword, making the rest parameter a suitable alternative in such use cases.

The spread operator

The Spread operator allows us to unpack all the array elements and object properties. It is particularly useful to extend an array or object and to create shallow copies of them.

Some key points to remember regarding the spread operator:

Extending array and object

Extending an array or object is one of the primary use cases of the spread operator.

// Extend an array
const numbers = [1, 2, 3];

const extended = [...numbers, 4, 5, 6];

console.log(extended); // [ 1, 2, 3, 4, 5, 6 ]

// Extend an object
const dev = {
  occupation: 'Software developer',
  isActive: true,
};

const john = {
  name: 'John',
  age: 30,
  ...dev,
};

console.log(john); // { name: 'John', age: 30, occupation: 'Software developer', isActive: true }

In these examples, we have used the spread operator to extend both the array and object. In the first example, we've created an extended array with all the elements from the numbers array. In the second example, we did the same, creating the john object with all the properties from the dev object.

Notice that in both cases, we've used the spread operator to copy all the elements from the array and properties from the object to another array and object.

Creating a shallow copy of an object

With the spread operator, we can create a shallow copy of an object.

const john = {
  age: 30,
  hobbies: ['Reading'],
};

const johnCopy = {
  ...john,
};

// Change john's age
john.age = 40;

// Add properties to hobbies array
john.hobbies.push('Coding');

console.log(johnCopy); // { age: 30, hobbies: [ 'Reading', 'Coding' ] }

In this example, we've created a john object. Next, we've created the johnCopy object by copying all the properties from the john object in it using the spread operator.

Moving on in the code, we've updated john's age to '40' and added 'Coding' to the hobbies array. Now, taking a look at the johnCopy object, we can see that the age is still '30', but the hobbies array is updated and now contains both 'Reading' and 'Coding'.

This proves that the spread operator only truly copies the top-level properties in an object, not the nested arrays and objects. So, updating the nested arrays and objects will impact both the original and copied objects. This is an important behavior to be aware of.

This wraps up our discussion about the rest and spread operator in JavaScript. I hope you've learned a thing or two from this article. Feel free to share this article if you find the content useful.

Share this article with your friends

Copy URL

Elevate your JavaScript and freelance journey

Supercharge your JavaScript skills and freelance career. Subscribe now for expert tips and insights!