Spread it and take the Rest

Sean
SLTC — Sean Learns To Code
3 min readNov 14, 2022

Today I learn something new about things that I thought I already knew it: what the three dots ... syntax means in JavaScript.

The Spread operator

This is not a new thing to me. The Spread operator is most often used when we need to create a new JavaScript object based on a few existing others. For instance, let’s look at the piece of code below

const foo = {
one: 1,
two: 2,
};
const bar = {
three: 3,
four: 4,
};

// now create a object that is the union of foo and bar
const fooBar = {
...foo,
...bar,
};
console.log(fooBar); // {(4) {one: 1, two: 2, three: 3, four: 4}

If you have worked with updating an application state in Redux you should find yourself using the spread syntax a lot as you create a new state object based on the current state object and the new data included in the action. The spread operator has proven to be very handy for applications whose states grow tremendously over time.

More on the Spread operator can be found here.

The Rest syntax

The JavaScript’s documentation of Mozilla has an entry for the Rest parameters. Let’s take a look at some code.

const sum = (...numbers) => {
return numbers.reduce(
(previous, current) => previous + current,
0,
);
}
console.log(sum(1,2,3)); // 6
console.log(sum(1,2,3,4)); // 10
console.log(sum(1,2,3,4,5)); // 15

In this example the Rest syntax is used with the numbers parameter to make sum a variadic function, i.e. a function that accepts a variable number of arguments. This is not a new thing to me, either!

What is new to me is that today I learned that the usage of the Rest syntax is not limited to just parameters.

const arr = ["one", "two", "three", "four"];
const [one, two, ...above] = arr;
console.log(one); // "one"
console.log(two); // "two"
console.log(above); // (2) ["three", "four"]

In the example above, the Rest syntax is used in combination with the array destructuring syntax to create a new array that is composed of elements that are not explicitly picked out as part of the destructuring action.

We can find ourselves taking advantage of the Rest syntax in situtations such as the one below in React

export const List = ({items}) => {
return (
<ul>
{items.map(({ itemId, ...item}) => {
return (
<Item key={itemId} {...item} />
)
})}
</ul>
);
}

Although the ... does appear in the area where we define the parameters of the callback function that is passed to map , note that this usage of the Rest syntax is not for creating a variadic function. It’s actually the combination of the Rest syntax and object destructuring. The code can be rewritten as follows to make it clearer how the Rest syntax is used.

export const List = ({items}) => {
return (
<ul>
{items.map((props) => {
const { itemId, ...item } = props;
return (
<Item key={itemId} {...item} />
)
})}
</ul>
);
}

Where to Spread and where to Rest?

So, if one looks at a code snippet, how do they tell if the three dots that they are looking at is a Spread or a Rest?

The rule of thumb here is to understand if the three dots notation is used on the left hand side (LHS) or the right hand side (RHS) of an assignment.

From the examples above, we know that when the Rest syntax is used with destructuring, it stays on the left hand side of an assignment.

Meanwhile, the Spread operator is used to create a new object so it has to be on the right hand side of an assignment.

As for the case when the Rest syntax is used with parameters, one way to reason about it is to think of the parameters that have the Rest syntax a bunch of variables created by destructuring the arguments object, which means the three dots stay on the left hand side of the assignment.

So, rest in the left because spread is always right!

--

--