# Function parameters

In our introduction to JavaScript functions, we already had a brief look at function parameters. I made the argument that parameters are an essential part of writing good functions, as they will allow you to pass values to the function and let the function act on these values. And since parameters are so important to functions, I would like to dig deeper into all the ways you can use them to your benefit and how they work behind the scenes.

## Multiple parameters

To begin with, I want to stress that even though our previous examples only showed a single parameter, JavaScript functions can of course handle multiple parameters just as easy. Here's an example:

```
function AddNumbers(n1, n2, n3)
{
return n1 + n2 + n3;
}
alert(AddNumbers(2, 3, 5));
```

Many programming languages requires that if a function has X parameters defined, and none of them are optional, you are required to pass in the same amount of values when calling the function. However, JavaScript is not that strict. In fact, it will allow you to pass as many values to a function, no matter how many parameters it defines.

This behavior can sometimes lead to unexpected behavior, because what happens when a parameter, expected by the function, is not present? Let's try it out:

```
function AddNumbers(n1, n2, n3)
{
return n1 + n2 + n3;
}
alert(AddNumbers(2, 3));
```

As you can see, the function is exactly the same as before, but this time, I only pass in two numbers when I call it. The result will be "NaN" (Not a Number), because the third parameter is now undefined and JavaScript is not able to work with that when doing addition.

### Basic parameter validation

So, when you write your functions, you may want to make sure that you do some validation before using the parameters, unless you know for a fact that only yourself will be calling this function and that you will always supply the expected parameters. Here's a version where we do some very basic validation to make sure that we have the parameters we need:

```
function AddNumbers(n1, n2, n3)
{
if(n3 === undefined)
n3 = 0;
return n1 + n2 + n3;
}
alert(AddNumbers(2, 3));
```

Since the function is called AddNumbers, I assume that at least two parameters are always passed, so I only validate the third parameter. I simply check if n3 is "undefined" - if so, I set it to 0 before doing the addition, so that it won't impact the calculation in any way.

### The arguments variable

Of course, a lot of other things could go wrong in the example above - for instance, the caller of the function could be passing in non-numeric text strings or something like that. How much validation you want to do is up to you, but in case you want to do even more validation, you may get some help from the **arguments variable**.

When you're inside of a function, JavaScript allows you to access a magic variable called arguments (remember, parameters are sometimes also called arguments), which is basically an array-like structure of parameters passed to the function. Notice the distinction here - it doesn't tell you anything about the expected/defined parameters, only about the actual values provided by the caller. Let's see an example of how it works, to create a bit more validation for our function:

```
function AddNumbers(n1, n2, n3)
{
if(arguments.length < 3)
{
alert("Please provide exactly 3 numerical values!");
return NaN;
}
for(let i = 0; i < arguments.length; i++)
{
if(isNaN(arguments[i]))
{
alert("Please provide exactly 3 numerical values!");
return NaN;
}
}
return n1 + n2 + n3;
}
let result = AddNumbers(2, 3, 4);
if(!isNaN(result))
alert(result);
```

So, this definitely made our very simple function a lot more complex, but as you will realize once you get more into programming, validation of any type will often have that effect on your code.

In our function, we now use the arguments variable to check two things: First, we check the length property, to make sure that at least 3 values was passed to it. We then loop through the arguments (because it's an array, so we can do that) and check each argument with the isNaN (short for is-not-a-number) function - all parameters must be numbers. If any of this fails, we show an alert and return NaN, indicating that the function failed.

There are a LOT of ways to deal with parameter validation, and showing alerts based on it is probably not among the most popular approaches, but remember that this example needs to illustrate a point. A more elegant approach would have probably included exceptions, but we'll get to that later on.

### Rest parameters

Sometimes you want your functions to take any number of parameters. Our AddNumbers() function is actually a fine example of this, because why only allow for 2 or 3 numbers to be added? No reason to have any limits here. Of course, we could use the **arguments** variable to simply go in and grab all user-specified values inside the function, much like we did in the validation example above, but it would not be obvious to the caller of the function that this was possible.

For these situations, JavaScript offers you "rest parameters". It's a special type of parameter, prefixed by three dots, to indicate that this parameter can accept multiple values. Let's try rewriting our AddNumbers() function to use a rest parameter:

```
function AddNumbers(...numbers)
{
let result = 0;
for(let i = 0; i < numbers.length; i++)
result += numbers[i];
return result;
}
let result = AddNumbers(1, 2, 4, 8, 16, 32);
alert(result);
```

Notice here that the function parameters from before is now just one parameter, called *numbers*, and prefixed with three dots to indicate that it's a rest parameter. Inside the function, we treat the *numbers* parameter like an array and loop through it to add all the numbers.

You are free to use regular parameters for your function along with a rest parameter, but just remember the following rules: There can only be one rest parameter per function, and it has to be the last parameter in the list, like this:

```
function DoStuff(stuff1, stuff2, ...stuffings)
{
}
```

### Spread syntax

Rest parameters are quite new to JavaScript, introduced in the ES6 specification. Therefore, you will sometimes run into situations where you have an array of values which you would like to pass to a JavaScript function, which takes an undefined number of parameters, but does it in the old-school way (using the arguments variable instead of rest parameters).

An example of this, is the Math.max() function, which takes any amount of numbers and returns the biggest one. It expects you to provide each value as a regular parameter, like this:

`alert(Math.max(1, 42, 117, 1042));`

But if you already have an array of numbers that you would like to check, maybe because you have a LOT of numbers, specifying them manually as parameters doesn't make sense. For this, you can use the **spread syntax**, which will take your array and expand it to a list of regular parameters. It uses the same notation as the one we saw for rest parameters - simply prefix the variable name with three dots to apply the spread operation:

```
let numbers = [1, 42, 117, 1042];
alert(Math.max(...numbers));
```

## Summary

As you can see from all of the above examples, JavaScript parameters offers you quite a bit of flexibility. Here are the key take-aways from our detailed walkthrough of parameters so far:

- A function can define 0 or more parameters, but the caller of the function is not forced to provide values for all of them
- The
**arguments**variable, available inside of a function, will allow you to access all arguments passed to the function, in an array-like object - Rest parameters is the new, cleaner way of specifying a function which can take an endless amount of arguments