Register to get access to 15+ free programming courses with interactive exercises

Let's try to implement a very simple function that sums up the numbers. First, let's define the `sum()`

function, which takes two numbers as input and returns their sum:

```
const sum = (a, b) => a + b;
sum(1, 2); // 3
sum(-3, 10); // 7
```

So far, everything is simple and straightforward. Difficulties arise with additional requirements: what if we want to sum up not two but three numbers? Or five, or even ten? Writing a separate function to handle each case is obviously a bad idea:

```
const sumOfTwo = (a, b) => a + b;
const sumOfTree = (a, b, c) => a + b + c;
const sumOfTen = (a, b, c, d, e, f, g, h, i, j) => a + b + c + d + e + f + g + h + i + j; // ugh...
// const sumoOfThousand = ???
// const sumOfMillion = ???
```

It is necessary that a single function can work with a different number of arguments. How do you do that?

You may notice that there are functions in the standard JavaScript library that can take different numbers of arguments. For example, the signature of the Math.max() function is defined as follows:

```
Math.max([value1[, value2[, ...]]])
```

It tells us that you can pass any number of elements to `Math.max()`

and they are optional:

```
Math.max(10, 20); // 20
Math.max(10, 20, 30); // 30
Math.max(10, 20, 30, 40, 50); // 50
Math.max(-10, -20, -30); // -10
```

In terms of calling, nothing unusual, just a different number of arguments. But the definition of a function with a variable number of arguments looks unusual:

```
const func = (...params) => {
// params is an array containing all
// arguments passed in the function call
console.log(params);
};
func(); // => []
func(9); // => [9]
func(9, 4); // => [9, 4]
func(9, 4, 1); // => [9, 4, 1]
func(9, 4, 1, -3); // => [9, 4, 1, -3]
```

The colon character `...`

before a formal parameter name in the function definition denotes a rest operator. Writing `...params`

in the `func()`

definition from the example above literally means the following: "place all arguments passed in the function call into the `params`

array".

If no arguments are passed at all, the `params`

array will be empty:

```
func(); // => []
```

You can pass any number of arguments to a function - all of them will go into the `params`

array:

```
func(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

Arguments can be of any type - numbers, strings, arrays, etc:

```
func(1, 2, 'hello', [3, 4, 5], true);
// => [1, 2, 'hello', [3, 4, 5 ], true]
```

Now we have enough knowledge to rewrite our `sum()`

function using the rest operator so that it can sum any number of numbers (not just two numbers, like now):

```
const sum = (...numbers) => {
// The default is 0, since the sum of nothing is 0
let result = 0;
for (const num of numbers) {
result += num;
}
return result;
};
sum(); // 0
sum(10); // 10
sum(10, 4); // 14
sum(8, 10, 4); // 22
```

https://repl.it/@hexlet/js-functions-rest-operator-sum

In that context, an array can be thought of as "optional arguments" that you can either not pass at all or pass as many as you want. But what if we want a function to have two ordinary ("required") named parameters and the rest to be optional and stored in a rest-array? It's simple: when defining a function, we first specify the standard named formal parameters (e.g., `a`

and `b`

) and add a rest-array at the end:

```
const func = (a, b, ...params) => {
// the 'a' parameter contains the first argument
console.log(`a -> ${a}`);
// // the 'b' parameter contains the second argument
console.log(`b -> ${b}`);
// params contains all arguments
console.log(params);
};
func(9, 4);
// => a -> 9
// => b -> 4
// => []
func(9, 4, 1);
// => a -> 9
// => b -> 4
// => [1]
func(9, 4, 1, -3);
// => a -> 9
// => b -> 4
// => [1, -3]
func(9, 4, 1, -3, -5);
// => a -> 9
// => b -> 4
// => [1, -3, -5]
```

The same can be done for a single argument:

```
const func = (a, ...params) => {
// ...
};
```

and for three:

```
const func = (a, b, c, ...params) => {
// ...
};
```

This idea can go on and on, making as many arguments as required mandatory. The only restriction: the rest operator can only be used for the last parameter. That is, such code is syntactically incorrect:

```
const func = (...params, a) => {
// ...
};
```

That one, too:

```
const func = (a, ...params, b) => {
// ...
};
```

This is why the operator is called *rest*, that is, it organizes the storage of the "rest" ("remaining", last) parameters.

The Hexlet support team or other students will answer you.

- Article “How to Learn and Cope with Negative Thoughts“
- Article “Learning Traps“
- Article “Complex and simple programming tasks“
- Lesson “How to get the most out of your learning on Hexlet“

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Programming courses for beginners and experienced developers. Start training for free

- 130 courses, 2000+ hours of theory
- 1000 practical tasks in a browser
- 360 000 students

Our graduates work in companies:

Suggested learning programs

From zero to a developer. Refunds in case you won't get a job

Profession

New
Development of front-end components for web applications

start anytime
10 months

- Ask questions about the lesson
- Test your knowledge in quizzes
- Practice in your browser
- Track your progress

Sign up or sign in

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.