Table of Contents

## Define a function

In this article, we are going to focus on defining our own custom functions in JavaScript.

A function can be seen as a piece of code wrapped in a value, which allows us to reuse that piece of code over and over again. In this article, we are going to talk about three different ways we can define a function in JavaScript.

The first method is to define functions as values, and bind that value to a name (like how we defined variables in the previous article).

```
let square = function(x) {
return x*x;
};
```

The function is created with the keyword `function`

, and it will take a set of parameters as input, in this case, only `x`

.

A function should also have a body where you return an output using the keyword `return`

, or have some kind of side effect.

Finally, the function as a value will be assigned to the name `square`

, which we need to use to execute/call this function.

Also remember that the semicolon (`;`

) at the end is necassary, because it is still a full statement where you declare a binding, except the value here is a function.

```
console.log(square(10));
// -> 100
```

A function can have more than one parameter or no parameters at all (an empty set of parameters).

```
const sleep = function() {
console.log("zzzzzzzzzzzzzzzzzzzzzz");
};
```

```
var multiply3 = function(x, y, z) {
return x * y * z;
};
```

As you can see, it is possible for a function to have only a side effect and not return anything.

The second method is slightly shorter, by declaring a function using the `function`

keyword, and it doesn’t require a semicolon at the end:

```
function square(x) {
return x * x;
}
```

The method also allows us to do something like this:

```
sleep();
multiply3(2,3,4);
function sleep() {
console.log("zzzzzzzzzzzzzzzzzzzzzz");
}
function multiply3(x, y, z) {
return x * y * z;
}
```

Here we put the function declarations after the statement that calls them, and the code still works. Now, we can put all the functions in one place, which is a good thing for future maintenance.

Finally, let’s talk about arrow functions. Instead of the keyword `function`

, we can use an arrow (=>) to declare a function.

```
const square = (x) => {
return x * x;
}
```

This is the exact same `square()`

function we saw before, and it works exactly the same. Then why does JavaScript have both arrow functions and the `function`

keyword? While, in some cases, it allows us to write shorter functions.

If the function only has one parameter, then you can omit the parentheses around the parameter list. And if there is only one statement in the function body, the curly braces and the `return`

keyword can also be omitted.

Then, our `square()`

function becomes:

`const square = x => x * x;`

### Bindings and Scopes

Before we go deeper into the topic of functions, let’s go back to the first method. You may have noticed that we defined the functions in the examples using different keywords, `let`

, `const`

and `var`

. What exactly are their differences?

First, we need to understand the concept of scope. It is the part of the program in which the binding is accessible. If a binding is defined outside of any functions or blocks (blocks can be `if`

statements, `for`

or `while`

loops, etc.), then you can refer to that binding wherever you want. This is called a global binding.

If the binding is declared inside a function or block using `let`

or `const`

, that binding will only be accessible from inside the function/block, and that is called a local binding. However, if the binding is defined using the keyword `var`

, then that binding will also be accessible from outside of the function/block.

```
let x = 10;
if (true) {
let y = 20;
var z = 30;
console.log(x + y + z); // -> all three variables are accessible here
// -> 60
}
console.log(x + z); // -> you cannot "see" y from here, but z is still accessible
```

Now, what are the differences between `let`

and `const`

? As the name suggests, `const`

stands for constant, meaning once a binding is declared using `const`

, you cannot change its value (unlike `let`

).

## Optional Arguments

JavaScript is very broad-minded when it comes to the number of parameters you pass to the function. For example, we have the `square()`

function we defined before, which is supposed to take one argument.

```
function square(x) { return x * x; }
console.log(square(4, true, "qwerty"));
```

In this example, we gave the `square()`

function more than one argument, and it simply ignores the extra arguments and computes the square of the first one.

And if we passed too few arguments, those missing parameters will be assigned the value `undefined`

instead of giving you an error.

The downside of this is, of course, when you accidentally make a mistake, no one will tell you about it. So, even though it technically works, you should never rely on this, it could give you some unexpected results. Instead, you should always be careful how many parameters you need, and how many arguments you are passing to the function.

### Rest Parameters

However, what if you don’t know how many parameters you need? For example, you are designing a function that finds the maximum number in a series of numbers, but you don’t know how many numbers are in the series, so you need to design a function that takes any number of arguments.

To write a function like this, you need to put three dots before the function’s last parameter:

```
function max(...numbers) {
let result = -Infinity;
for (let number of numbers) {
if (number > result) {
result = number;
}
}
return result;
}
max(1, 2, 3, 4, 5, 6, 7);
```

Now, the parameter `numbers`

(it is called the rest parameter) will be bound to an array, and the function will return the maximum number in that array.

An array is a list of items, in this case, we have `[ 1, 2, 3, 4, 5, 6, 7 ]`

, and `for (let number of numbers)`

is how we can iterate over all items in this array. We’ll discuss arrays in the next article.

## Recursion

Finally, let’s talk about the concept of recursion. Recursion is when a function calls itself. The most typical example is how we calculate the power of a number.

```
function power(base, exponent) {
if (exponent == 0) {
return 1;
} else {
return base * power(base, exponent - 1);
}
}
```

Notice that in line 5, the function power called itself with parameters `base`

and `exponent - 1`

.

I know this is a bit confusing, but don’t worry, to understand this code, let’s plug in some numbers. Let’s try to calculate `10^5`

(10 to the power of 5).

In the first step, we simply plug in the numbers, and the function returns `10 * power(10, 4)`

. Then we need to calculate `power(10, 4)`

. Plug in the numbers, and we get `10 * power(10, 3)`

, which means `power(10, 5)`

equals `10 * 10 * power(10, 3)`

.

And we keep repeating the same steps until we get `10 * 10 * 10 * 10 * 10 * power(10, 0)`

. Because `power(10, 0)`

returns `1`

, eventually we get `power(10, 5)`

equals `10 * 10 * 10 * 10 * 10`

.

This is a very elegent way of defining exponentiation, but unfortunatly, this method is about three times slower than using loops in JavaScript. This is a dilemma that programmers face all the time, we have to choose between simplicity and speed, because almost any program can be made faster by making it bigger. It’s up to the programmer to decide on an appropriate balance.