Rest in JavaScript: gathering the remaining arguments or properties

Rest gathers every remaining value into an array or object. Its syntax, its positioning rule, and what separates it from spread.
3 min read
Believemy logo

The same three dots as spread, the exact opposite behavior. Where spread opens a box, rest closes one: it picks up everything that was not named and files it into a single variable.


Definition

Rest, written as three dots in front of a name, gathers the remaining values into an array or an object. It shows up in two places: a function's parameter list, and a Destructuring.

JAVASCRIPT
// Rest parameter: a genuine array
function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}

console.log(sum(1, 2, 3, 4)); // 10

// With named parameters in front
function head(first, ...tail) {
  return { first, tail };
}

console.log(head("a", "b", "c")); // { first: "a", tail: ["b", "c"] }

It is the direct replacement for the arguments object, with three advantages: the result is a real array, the variable carries a meaningful name, and the form works inside arrow functions.


One positioning rule

Rest must always come last, which follows from its very definition: gathering what remains only makes sense once the rest is known.

JAVASCRIPT
// Rejected by the engine
// function f(...values, last) {}  // SyntaxError

// Accepted
function f(first, ...values) {}
Good to know

A rest parameter does not count toward a function's length property, which reports how many parameters are expected. A function written function sum(...n) therefore reports length as zero, which surprises anyone inspecting code.


Rest in destructuring

This is its most elegant use, and the least known among beginners. It removes a property from an object without writing a loop or modifying the original.

JAVASCRIPT
// On an array
const [first, ...others] = [1, 2, 3];
console.log(others); // [2, 3]

// On an object: isolate one key and keep the rest
const user = { id: 7, name: "Ada", password: "secret" };
const { password, ...safe } = user;

console.log(safe); // { id: 7, name: "Ada" }

That last line is a very common server-side pattern: stripping a sensitive field before sending an object to the client. The original stays intact, and the new object never holds the discarded property.


Frequently asked questions

Question

How do I tell rest from spread while reading?

Look at which side of the equals sign the three dots sit on, or whether they appear in a parameter list. On the left of an assignment or in a parameter list, they gather: that is rest. On the right, or inside a function call, they spread: that is Spread (...).


Question

What does the parameter hold when no argument is passed?

An empty array, never undefined. That is a quiet but real advantage over the arguments object: you can chain an array method straight away, without first checking that there is anything to process.


Question

Does object rest make a deep copy?

No, and it shares that limit with Spread (...): only the first level is copied. If the object holds a property that is itself an object, both versions share that nested value. For a genuinely independent copy, go through structuredClone.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.