Functions
Tags: react, javascript, beginners, functional
Published: 2020-10-28 21:27:19

# Foreword

If you're completely new to _functions,_ start here: {% link https://dev.to/awesomecoder123/intro-to-functions-in-js-3l35 %}

# Overview

_Functions_ is an incredibly deep topic for any programming language. Here, we just give some basic overview based on some of the most common ❓s that I receive from students.

# Parameters and Arguments

When we see something like: `function adder(num1, num2)`, `num1` and `num2` are _parameters._ Said _parameters_ will be bound to _arguments_ when we invoke/call/run the _function._ So, in the case of `adder(1, 2)`, `1` would be _bound_ to `num1` and `2` would be _bound_ to `num2`. This _binding_ will endure throughout the function's _scope_ - from the opening `{` to the closing `{`.

# Variadic Parameter Functions

Sometimes, we wish to write a _function_ that can accept an unlimited number of _arguments._ We can use _rest parameters `...`. This will grab all of the _arguments_ and _bind_ them as an _array_ to the _parameter._

```javascript
// nums will be an array.
function addManyNumbers(...nums) {
  // TODO: Use 'reduce' to add up and return all the numbers
}

// Send as many arguments as you want
addManyNumbers(1, 2, 3, 4, 5)
```

# `return`

If you don't include a `return` in your `function`, it will _implicitly return_ `undefined`. This is not generally desirable. AMAP, you should include an _explicit `return`._

That `return` _value_ could then be `log`ged or just _bound_ to another _variable_ for later use.

```javascript
function adder(num1, num2) {
  return num1 + num2
}

const sum = adder(1, 2);
```
# Arrow Syntax

As of ES2015/ES6+, we can save some typing. To create `adder` as we had mentioned 👆🏽:

```javascript
const adder = (num1, num2) => {
  return num1 + num2
}
```

_If our **function** only has 1 **statement,** we can rely on an **implicit `return`.**_ This means we get rid of `{`, `}` and `return`, creating a beautiful '1-liner': `const adder = (num1, num2) => num1 + num2` 🤓.

# Default Parameters

We can give our _parameters_ default values such that if we invoke the _function_ without explicitly passing in a _value,_ the default will be used.

{% replit @CodeFinity/Default-Params %}

Above, we first invoke w/o any _arguments._ So, both default values, `1` and `2` were used. In the second case, we _did_ pass in our own _value_ for the first _parameter,_ `5`. Only the second _parameter_ used its default value, `2`.

# Methods

A _method_ is nothing but a _function_ that is _scoped_ inside another _object literal._

{% replit @CodeFinity/Callback-Functions %}

There are many built in _methods_ that we use all of the time. For example, `console.log()`, where `log` is a function 'scoped' to the `console` object.

This can lead us to the basis of JS's prototypal OOP features - a topic for another post! 😅

# Callback Functions

JS functions are _first class 🏆._ Anything we can do with other data types, we can do with _functions._ We can pass _functions_ as _arguments_ into other _functions_ - _callback functions._ We can also _return functions from other functions._

Callbacks are great for 'event-driven' operations. For example, DOM interactions such as handling `"click"`s: `addEventListener("click", () => {`.

There is a function that gets 'called back' whenever the browser notifies JS of a 'click event.'

# Closures - Returning a Function

In this pattern, we are utilizing a _function factory 🏭._ It's a _function_ that _returns_ other _functions._ Along the way, the _argument_ passed in to create that 'returned function' becomes _enclosed,_ with a _bound reference_ that persists as long as that 'created function' persists. 

_Closures_ is a tough concept to learn about. The below example usually does the trick in my classes to illustrate the pattern at least:

{% replit @CodeFinity/Closure %}

# 'Pure' Functions

This too could be a whole separate topic, but generally, 'pure functions' are those that:

i) given the same input always return the same output
ii) Have explicit `return`
iii) Don't depend on anything outside of their _scope._

I liken these to 'copy/paste' functions. If they are written correctly, these functions could be copied and pasted into any codebase and _invoked_ w/o any issue. They are 'independent' functions.' 

Don't overthink 🧠 this. `const adder = (num1, num2) => num1 + num2` _is_ a **pure function.** We can copy/paste it anywhere and it doesn't care about anything outside of its _scope._ It just sits around until we send it 2 numbers. Then it does its job w/o touching anything else in our program 👍🏽.

# 🎶 about some 'Best Practices' and 'Clean Code'

I'm going to highlight a couple of the recommendations given [here](https://github.com/ryanmcdermott/clean-code-javascript#functions):

1. Functions should do 1 thing. If you can't clearly name your function, then chances are it's doing too much. Regarding naming, I personally try to start the name with a verb to make it clear that it's a function and that it 'does' something.
2. Functions should avoid taking more than 2 parameters. If you _need_ more, rely on _object destructuring._ Here's an example:

{% replit @CodeFinity/Function-Object-Destructuring %}

We invoke the _function_ by passing in an _object literal_ as the _argument._ This is then _destructured._ You can see that we can still provide default values as previously discussed 👆🏽.

You might also notice that our _parameter_ as a whole has a _default value, {} 🤔._ I'll leave it as an exercise for you to deduce why we might want that. **Hint:** Try 🏃🏽‍♂️ the _function_ w/o _any_ arguments with and w/o that `{}` default.

---

There's a lot more that could be said on this topic, but after a while too much theory is counterproductive. You should go practice writing code 👩🏽‍💻 while keeping these things in mind 🧠. Then, come back and post your ❓s for discussion. You have more than enough to start writing ✍️ your own functions.