Function
Tags: javascript, beginners, codenewbie, tutorial
Published: 2022-07-02 11:08:08

Function helps us organize our code and easier to reuse our code. We use function to group a piece of code together. Let's take a look at the basic usage of function.

## Make a function

Use the keyword `function`, give it a name e.g. `add`, followed by parenthesis `()` and brackets `{}`.
```js
function add() {
  
}
```

We write what we want to do inside `{}`, and what information we need as parameters inside `()`. Parameters are separated by `,` and will be used inside `{}`. We can think parameters as declaring [variables](https://dev.to/gohomewho/variable-2n4g), and the variables will be reassigned values when the function is called. 
```js
function add(a, b) { // let a, b
  console.log(a + b)  
}
```

We can optionally give parameters a default value.
```js
function add(a, b = 10) { // let a, b = 10
  console.log(a + b)  
}
```

Use `return` keyword to return a value from a function. If we don't explicit `return` something in a function, it will return `undefined` anyway.
```js
function add(a, b) {
  console.log(a + b)  
  return a + b
}
```

### Function declaration
When we make a function like above, it's called [function declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function).


### Function expression
[Function expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function) is another way to make a function. Similar to declaring a variable, we use `=` to assign a value to a variable, and the value is a function.

This is how we make a function expression.
```js
const add = function(a, b) {
  return a + b
}
```
Notice that between `function` keyword and `()`, we don't need to provide another name. 



#### Arrow function
Arrow function is a shorthand to make a function. Here we make one arrow function using function expression as an example. 

`function() {}` becomes `() => {}` 
```js
const add = (a, b) => {
  return a + b
}
```

If we only have one statement in an arrow function, we can omit `return` keyword and `{}`. It will still return the result of that statement.
```js
const add = (a, b) => a + b
```

Returning an object in one line.
```js
const add = (a, b) => { return { result: a + b } }
// same as
const add = (a, b) => ({ result: a + b })
```

---


## Call a function
We write the name of a function and `()` to call a function. We can pass arguments (_or parameters if you will_) inside `()`. Note that if a function have a parameter without default value and we don't pass argument either, the value of that parameter will be `undefined`.

`add()` call the function `add`, and the arguments `(1, 2)` are passed to `(a, b)` respectively. 
```js
function add(a, b) {
  console.log(a + b)  
  return a + b
}

add(1, 2)
```

The function `add` return a value, so we can store the result with a variable.
```js
const result = add(1, 2)
```

A common mistake is that we don't get the correct result of what we expect from a function and we use that result to do other things. Maybe we don't pass the correct arguments to the function or we forget to return a value from the function, or something else. In this case, we can add a control flow for safety.
```js
const result = add(1, 2)
if(Number.isNaN(result) === false) {
  // do something with the result
}
```

### The difference between function declaration and function expression

We learned how to make a function declaration and a function expression earlier. The difference between them is that we cannot call a function expression before it is initialized.

We can call a function declaration like this. 
```js
add(1, 2)

function add(a, b) {
  console.log(a + b)  
  return a + b
}
```
Notice that the function is called before it is defined. This is because of [hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting), JavaScript moves function declarations to the top of our code. 

Variables are also hoisted, but they are handled different than function declarations. So we cannot call a function expression before it is defined.
```js
add(1, 2)
// Uncaught ReferenceError: add is not defined
const add = (a, b) => a + b
```



### Callback function
We can pass another function as an argument to a function. So we can do something else when we call the same function.

The third parameter `doSomething` is expected to be provided with a function because we use it like a function `doSomething()`. 
```js
function add(a, b, doSomething) { // let a, b, doSomething
  doSomething()
  return a + b
}
```

Make a callback function and pass it to `add`.
```js
function log(a, b) {
  console.log(a, b)
}

add(1, 2, log)
```

We didn't pass arguments to the callback function `doSomething` when we declare `add` function above. So `doSomething` which is the `log` function in this case, cannot log the result we want.
```js
// simulate what happens when we call add(1, 2, log)
function add(a, b, doSomething) { // let a, b, doSomething
  // a = 1
  // b = 2
  // doSomething = log

  doSomething() // this will console log undefined undefined
  return a + b // 3
}
```

Fix it
```js
function add(a, b, doSomething) { // let a, b, doSomething
  doSomething(a, b) // pass arguments to this callback function
  return a + b
}
```
Callback function is just another function, if we don't pass arguments when we call it, the default values of parameters will be used.


We can declare callback function directly when we call a function. The third argument we pass to `add` is a function, and it will be used inside `add`.
```js
// normal anonymous function
add(1, 2, function(a, b) {
  console.log(a, b) 
})

// arrow function
add(1, 2, (a, b) => { 
  console.log(a, b) 
})
```

#### Realistic examples
Let's take a look at two example of where callback is used. Don't worry if you don't know `addEventListener` and `forEach`. We only need to understand how to pass a function to another function. 

We use [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) to register event listeners in browser. The first parameter it receives is the type of the event, the second argument is a callback that we can decide what we want to do. When the event is triggered, browser will call that callback and pass an event object as the first argument.

```js
button.addEventListener('click', (e) => {
  console.log(e)
})
```


[forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) is one of the Array methods, it takes a callback as the first parameter. `forEach` will loop through the array and call the callback with three arguments `element`, `index`, `array` on each item. 

```js
const array = [1, 2, 3, 4, 5]
array.forEach((entry) => {
  console.log(entry)
})
```

Note that the callback we declare only takes one parameter, but the callback will be called inside `forEach` with three arguments. It's up to us to decide whether we need to use those extra information. But if it doesn't call the callback with those arguments, we can never have access to those extra information in our callback.


---

## Wrap up 
We learn how to make a function, how to call a function, and how to use a callback function. Callback function can be weird at first glance, but essentially it is function. We only need to focus on how the function is declared and how the function is called.