A function is a JavaScript procedure — a set of statements that performs a task or calculates a value.

### Function declarations

A **function definition** (also called a function **declaration**, or function **statement**) consists of the `function`

keyword, followed by:

- The name of the function.
- A list of parameters to the function, enclosed in parentheses and separated by commas.
- The JavaScript statements that define the function, enclosed in curly brackets, {...}

`function multiply(x, y) { return x * y; }`

### Function Expressions

While the function declaration above is syntactically a statement, functions can also be created by a function expression.

Such a function can be **anonymous**; it does not have to have a name. For example, the function `multiply`

could have been defined as:

```
const multiply = function (x, y) {
return x * y;
}
multiply(5, 10) // 50
```

### Function scope

Variables defined inside a function cannot be accessed from anywhere outside the function, because the variable is defined only in the scope of the function. However, a function can access all variables and functions defined inside the scope in which it is defined.

`let a = 5, b = 10; function multiply() { return a * b; } multiply(); // 50`

### Closures

Closures are one of the most powerful features of JavaScript. JavaScript allows for the nesting of functions and grants the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to).

However, the outer function does *not* have access to the variables and functions defined inside the inner function. This provides a sort of encapsulation for the variables of the inner function.

`function sum (a, b) { if(b === undefined) { return function (b) { return a + b; } } return a + b; } sum(2)(5)`

### Arrow functions

An arrow function expression (previously, and now incorrectly known as **fat arrow** function) has a shorter syntax compared to function expressions and does not have its own this, arguments, super, or new.target. Arrow functions are always anonymous.

Two factors influenced the introduction of arrow functions: **shorter functions** and **non-binding of this**.

```
// shorter functions
const multiply = (a, b) => a * b;
multiply(2, 5) // 10
// syntax
const variable = (parameters) => {...statements}
```