Rest parameters in JavaScript

JavaScript

The short answer

Rest parameters (...) let a function accept any number of arguments and collect them into an array. It is the opposite of the spread operator — spread expands things out, rest collects things together.

How it works

function sum(...numbers) {
let total = 0;
for (const num of numbers) {
total += num;
}
return total;
}
sum(1, 2); // 3
sum(1, 2, 3, 4, 5); // 15
sum(); // 0

The ...numbers collects all the arguments into an array called numbers. You can pass as many arguments as you want.

Combining with regular parameters

You can use rest parameters with regular parameters. The rest parameter collects whatever is left:

function introduce(greeting, ...names) {
names.forEach((name) => {
console.log(`${greeting}, ${name}!`);
});
}
introduce('Hello', 'John', 'Jane', 'Bob');
// "Hello, John!"
// "Hello, Jane!"
// "Hello, Bob!"

greeting gets the first argument ("Hello"), and ...names gets the rest (["John", "Jane", "Bob"]).

Important: Rest parameters must always be the last parameter in the function.

// This works
function test(a, b, ...rest) {}
// This does NOT work
function test(...rest, a, b) {} // SyntaxError

Rest vs arguments

Before rest parameters, we used the arguments object:

// Old way
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}

There are a few problems with arguments:

  • It is not a real array — you cannot use map, filter, reduce on it directly
  • It does not work in arrow functions
  • It contains all arguments, you cannot separate some out

Rest parameters fix all of these:

// New way
const sum = (...numbers) =>
numbers.reduce((a, b) => a + b, 0);

It is a real array, works with arrow functions, and you can combine it with named parameters.

Destructuring with rest

You can use rest in destructuring too:

// Arrays
const [first, second, ...remaining] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(remaining); // [3, 4, 5]
// Objects
const { name, ...otherProps } = {
name: 'John',
age: 30,
city: 'NYC',
};
console.log(name); // "John"
console.log(otherProps); // { age: 30, city: "NYC" }

This pattern is very common in React for forwarding props:

function Button({ variant, ...rest }) {
return <button className={variant} {...rest} />;
}

The component takes variant for itself and passes everything else to the button element.

Interview Tip

When explaining rest parameters, always contrast them with the spread operator — they use the same ... syntax but do opposite things. Spread expands, rest collects. Also show the destructuring use case because it is very common in React code and interviewers love seeing that connection.

Why interviewers ask this

Rest parameters are used in everyday JavaScript and React code. Interviewers want to see if you know the difference between rest and spread (since they use the same syntax), if you know how rest parameters replaced the old arguments object, and if you can use them effectively with destructuring.