JavaScript Functions
Tags: javascript
Published: 2020-04-22 14:34:51

---
title: JavaScript Functions
published: true
date: 2020-04-22 06:00:00 UTC
tags: javascript
canonical_url: https://www.prestonlamb.com/blog/javascript-functions
---

## [tldr;](#tldr)

Every JavaScript application uses functions. In this blog post we’ll go over the basics of functions and arrow functions, providing default parameters to functions, passing named parameters to functions, and using the rest parameters in functions. By the end of this blog post, you should be comfortable with each of these parts of dealing with JavaScript functions. Everything we cover in this blog post can be used in modern browsers today.

## [Named Functions](#named-functions)

Let’s start with the most simple way to write a function. Here’s an example:

```js
function myFunction(arg1) {
	// Do something
}
```

Each named function starts with the `function` keyword. After that comes the name of the function. This is how you’ll reference and call the function later on. From the example above, the name would be `myFunction`. After the function name comes the argument list, enclosed in parentheses. The arguments, also called parameters, are optional but the parentheses are not. Then the function body starts and ends with curly braces. Inside the body of the function is where you’ll do your work. To call a function, you use its name, open parentheses, the list of arguments, and close parentheses.

```js
myFunction('hello');
```

Another way you can create a function is by assigning an anonymous function to a variable. An anonymous function is a normal function but it doesn’t have a name. You would only use these as callbacks or by assigning them to a variable. Let’s look at an example of assigning an anonymous function to a variable.

```js
const myFunction = function(arg1) {
	// Do something
}
myFunction();
```

You can call it in the same way too, as seen above. These are both valid ways of creating functions. In my experience, named functions are more common than assigning an anonymous function to a variable.

You can also have functions as attributes on objects. These functions have a special name: methods. It’s really the same thing though, and you can call it a method or a function. Everyone will know what you’re talking about. Here’s an example of a method and how to use it:

```js
function sayHi() {
    console.log (`Hi my name is ${this.name}.`);
}
const person = {
    name: 'Preston Lamb',
    sayHi
}
person.sayHi();

// or

const person = {
    name: 'Preston Lamb',
    sayHi: function () {
        console.log (`Hi my name is ${this.name}.`);
    }
}
person.sayHi();

// or

const person = {
    name: 'Preston Lamb',
    sayHi() {
        console.log(`Hi my name is ${this.name}.`)
    }
}
person.sayHi()
```

All three of these examples have the same result and are valid ways to add methods to an object. We’ll talk about arrow functions as methods next.

## [Arrow Functions](#arrow-functions)

Another type of function that’s common in JavaScript is a lambda function, or arrow function as it’s more commonly known. Arrow functions are especially great when being used as a callback, but you don’t only have to use them as callbacks. They’re quick to write and easy to use. Let’s take a look at how you can use arrow functions.

```js
const sayHi = () => console.log('Hi!');
sayHi(); // Hi!

const arr = ['Item 1', 'Item 2'];
arr.forEach((item) => console.log(item)); // Item 1 Item 2

const person = {
    name: 'Preston Lamb',
    doSomething: () => console.log('Does something');
}
person.doSomething(); // Does something
```

> Arrow functions do not have their own context, so in the last example they have no access to `this`. To learn more, reference [my article on the `this` keyword in JavaScript](/blog/javascript-this-keyword).

Arrow functions are great, and I normally reach for them mainly as callbacks. I don’t personally use them as the first example above, although it’s perfectly valid. If you don’t need any specific context in the function, an arrow function is a great option.

## [Providing Default Parameters to Functions](#providing-default-parameters-to-functions)

Another great feature of functions in ES6 is default function parameters. Default parameters makes it so that a parameter value is initialized with some value, but this initialized value will be overwritten by whatever is passed in to the function. This makes it so that there’s always some value in the parameter of a function; they won’t be `undefined` unless explicitly passed that way. Let’s look at an example where this would be helpful.

```js
function divide(top, bottom) {
    console.log(top / bottom);
}
divide(5); // NaN
```

Here we have a `divide` function that takes two numbers and returns the top divided by the bottom. When we call it in the above manner, without the second parameter, the result is `NaN`. That’s because the `bottom` parameter is `undefined` since nothing was passed in to the function. Then maybe we forget to check what type the return value of this function is elsewhere in our code, and we assume it’ll always be a number. But in this case we’d get an error elsewhere because `NaN` is not a number. So to prevent the error, we have to do checks on the result anywhere we may call the function. It’d be best if we never ran in to this problem though, right? So let’s provide some default parameters to this function.

```js
function divide(top, bottom = 1) {
    console.log(top/bottom);
}
divide(5); // 5
```

This time we call the function in the same way, but because we’ve provided a default parameter to the function for the `bottom` parameter, its value will always be 1 if nothing is passed in. So instead of getting `NaN`, we get `5` for our answer here.

This example is a little contrived, but here’s another example of something that I’ve run into in my job before. Let’s say we have a function that creates a new instance of an object with several attributes. Sometimes we want to give some starting values to the object, but other times we don’t. We can do this simply with default parameters.

```js
function dog(startingValues = {}) {
    const dogObject = {
        name: startingValues.name || '',
        breed: startingValues.breed || ''
    };

    return dogObject;
}

const duke = dog();
console.log(duke); // { name: '', breed: '' }

const max = dog({ name: 'Max' });
console.log(max); // { name: 'Max', breed: '' }
```

Without the default parameters, if we didn’t pass an object to the `dog` function, we would get an error: `cannot read property name of undefined`. In this case, default parameters work perfectly to prevent us from having errors in our application.

> You can have multiple default parameters in a function. Let’s say arguments two and three both have default parameters. If you want to use the default parameter for the second argument, but pass the third argument, you’re out of luck. You’d have to pass something as the second argument, even if it was `null`.

## [Named Parameters to Functions](#named-parameters-to-functions)

Another convenient feature of parameters in ES6 functions is named parameters. Sometimes the parameter list of a function gets really long, and it can be hard to know what each parameter should be. If you wrote the function, you might remember. But only when you first wrote the function. Then each time you come back to it you’ll have to look again and try to remember what each does. Or, you could use named parameters. To use named parameters, all you’ll need to do is pass a single object to the function instead of multiple parameters. It’s similar to what we did in the last section. But instead of naming the variable (like we did above `startingValues`) we will have access to each of the attributes of the object as variables inside the function. Let’s take a look at this. We’ll first show an example without named parameters, and an example with.

```js
function dogInfo(name, breed, age, foodPreference, likesToWalk) {
    return `The dog's name is ${name} and it is a ${breed}. It's age is ${age}, and it likes to eat ${foodPreference}. It ${likesToWalk ? 'does' : 'does not'} like to walk.`;
}
dogInfo('Duke', 'Labradoodle', '3 years', 'anything', true);
```

If we need to call this `dogInfo` function, we need to remember each one of these parameters, and more importantly the order has to be correct each time. Otherwise we’re not going to get the result we’re looking for. And looking at just the function above, what do some of those parameters actually mean? If I hadn’t written the function, I wouldn’t know what the `true` was for. Or the `anything` string. It can be really confusing, especially for other developers who look at your code. Now let’s try it with named parameters.

```js
function dogInfo({ name, breed, age, foodPreference, likesToWalk}) {
    return `The dog's name is ${name} and it is a ${breed}. It's age is ${age}, and it likes to eat ${foodPreference}. It ${likesToWalk ? 'does' : 'does not'} like to walk.`;
}
dogInfo({ name: 'Duke', breed: 'Labradoodle', age: '3 years', likesToWalk: true, foodPreference: 'anything' });
```

This time, it’s very clear what each item is that we’re passing to the function. The object we pass in has the attribute of each right next to it. The other thing is that in this manner there is no order for the attributes on the object. No matter how you order them, it’s still going to work. That’s so much better than the first function! Also, your IDE should give you help in knowing what you should pass as well. Let’s now combine named parameters and default parameters.

```js
function dogInfo({ name = 'Your Dog', breed = 'unknown', age, foodPreference, likesToWalk = true} = {}) {
    return `The dog's name is ${name} and it is a ${breed}. It's age is ${age}, and it likes to eat ${foodPreference}. It ${likesToWalk ? 'does' : 'does not'} like to walk.`;
}
dogInfo({ age: '3 years', foodPreference: 'anything' });
```

This time we only passed in the `age` attribute and the `foodPreference`, but due to default parameters we didn’t have any problems missing parameters, and we didn’t need to pass `null` as a parameter or anything like that. With named and default parameters, we can pass just the values we want and leave out the rest. This is really nice and really convenient.

## [Rest Parameters](#rest-parameters)

The last thing we’ll talk about is the `rest` parameters option in a function. What this allows you to do is to name a certain number of parameters to the function, and then catch the rest of them in an array. Let’s look at an example of this.

```js
function addition(setName, ...numbers) {
    const total = numbers.reduce((prev, next) => prev += next, 0);
    return `Total of ${setName}: ${total}`;
}

const result = addition('years', 1,2,3,4);
console.log(result); // Total of years: 10
```

What this function does is takes a parameter that is called `setName`, which is the name of the set of numbers we’re passing it. Then we capture the rest of the arguments passed to the function in the `numbers` array. It could be 0 to many arguments that are in that `rest` parameter. This is really convenient for when your function needs at least N arguments, but can use as many are as passed.

Now, this `numbers` parameter is different than the built in `arguments` attribute of a function. The biggest is that `arguments` includes all the arguments or parameters passed to a function. The `rest` parameter only includes all the parameters that weren’t named. The next big difference is that the `rest` parameter is actually an array. `arguments` is array-like, but you can’t use array methods (like `forEach` or `reduce`) on `arguments`. So you can use `arguments`, but it is different than a `rest` parameter.

## [Conclusion](#conclusion)

Knowing all the ways to declare functions and use functions and parameters will allow you to write the most efficient applications possible. They’ll also be more user friendly, in the case of named parameters for example. A little bit of practice and a little bit of learning will make these things come more easily and second nature to you.