## DEV Community

Manav Misra

Posted on • Updated on

# Foreword

If you're completely new to functions, start here:

# 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 `{`.

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.

``````// nums will be an array.
// TODO: Use 'reduce' to add up and return all the numbers
}

// Send as many arguments as you want
``````

# `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.

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

``````

# Arrow Syntax

As of ES2015/ES6+, we can save some typing. To create `adder` as we had mentioned ππ½:

``````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.

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.

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:

# '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:

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:

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.