Learn First-Class Functions in JavaScript
Tags: javascript, webdev, node, programming
Published: 2020-07-02 12:34:17

---
title: Learn First-Class Functions in JavaScript
published: true
description: JavaScript has first-class functions. This means functions can be treated like other values, which turns out to be incredibly important behavior to understand as you advance as a JavaScript developer.
tags: javascript, webdev, node, programming
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/1r8quglwpui2edsy0cu1.png
canonical_url: https://typeofnan.dev/first-class-functions-in-javascript/
---

*Please give this post a 💓, 🦄, or 🔖 if it you enjoy it!*

<hr />

JavaScript has first-class functions. This means functions can be treated like other values, which turns out to be incredibly important behavior to understand as you advance as a JavaScript developer. The following three bullets represent important first-class function behavior:

- Functions can be assigned to variables
- Functions can be passed as arguments to other functions
- Functions can be returned from other functions

Let's explore each of these bullets using basic examples and then bring it all together at the end with a couple more complex, real-world examples!

<hr />

I make other easy-to-digest tutorial content! Please consider:

- Subscribing to my [DevTuts mailing list](https://buttondown.email/devtuts)
- Subscribing to my [DevTuts YouTube channel](https://youtube.com/c/devtutsco)

<hr />

# Assigning Functions to Variables

Let's create a function that returns the text `"Hello"` and then assign that function to a variable creatively named `sayHello`.

```javascript
const sayHello = () => {
  return 'Hello';
};

console.log(sayHello());
// "Hello"
```

Pretty basic! Let's move on.

# Passing a Function as an Argument

Let's take the aforementioned `sayHello` function and pass it as an argument to another function. This other function will say hello to a particular person.

```javascript
const sayHelloToPerson = (greeter, person) => {
  return greeter() + ' ' + person;
};

console.log(sayHelloToPerson(sayHello, 'John'));
// Hello John
```

A quick note on what happens when we pass the `sayHello` function to `sayHelloToPerson`: within the `sayHelloToPerson` function, the variable `greeter` will now point to the `sayHello` function in memory. When we call `greeter()`, the function is called!

**Note:** I'd normally use template literals in this case (i.e., `` return `${greeter()} ${person}` ``), but didn't want template literal syntax to muddy the water in this example!

# Return a Function from Another Function

Maybe we don't alway want to say `"Hello"`, but rather want the choice of creating any number of different types of greeters. Let's use a function that lets us create greeter functions.

```javascript
const greeterMaker = greeting => {
  return person => {
    return greeting + ' ' + person;
  };
};

const sayHelloToPerson = greeterMaker('Hello');
const sayHowdyToPerson = greeterMaker('Howdy');

console.log(sayHelloToPerson('Joanne'));
// "Hello Joanne"

console.log(sayHowdyToPerson('Joanne'));
// "Howdy Joanne"
```

Our `greeterMaker` is a function that creates functions! Pretty nifty, right?

# Some Fun, Real-World Use Cases

Now that we checked out the basics of first-class functions, let's look at some real-world use cases!

## Object Validation

Perhaps you have a bunch of criteria that an object (e.g., new user information) needs to pass to be considered "valid." Let's create a function that iterates over all our criteria and returns whether the object is valid or not.

```javascript
const usernameLongEnough = obj => {
  return obj.username.length >= 5;
};

const passwordsMatch = obj => {
  return obj.password === obj.confirmPassword;
};

const objectIsValid = (obj, ...funcs) => {
  for (let i = 0; i < funcs.length; i++) {
    if (funcs[i](obj) === false) {
      return false;
    }
  }

  return true;
};

const obj1 = {
  username: 'abc123',
  password: 'foobar',
  confirmPassword: 'foobar',
};

const obj1Valid = objectIsValid(obj1, usernameLongEnough, passwordsMatch);
console.log(obj1Valid);
// true

const obj2 = {
  username: 'joe555',
  password: 'foobar',
  confirmPassword: 'oops',
};

const obj2Valid = objectIsValid(obj2, usernameLongEnough, passwordsMatch);
console.log(obj2Valid);
// false
```

If you're relatively new to JavaScript, it might take you several read-throughs to understand what's going on, but trust me, the payoff is great once you understand!

**Note:** If you're unfamiliar with the rest operator (`...`), this simply allows all remaining arguments provided to the function to be put into an array by the specified name.

## API Key Closure

Perhaps we have a situation where we want to connect to an API using an API key. We could add this key on every request, _or_, we could create a function that takes an API key parameter and returns functions that contain the API key with each request.

**Important: Don't put secret API keys in front-end code. Instead, imagine the following code is in a node-based back-end.**

```javascript
const apiConnect = apiKey => {
  const getData = route => {
    return axios.get(`${route}?key=${apiKey}`);
  };

  const postData = (route, params) => {
    return axios.post(route, {
      body: JSON.stringify(params),
      headers: {
        Authorization: `Bearer ${apiKey}`,
      },
    });
  };

  return { getData, postData };
};

const api = apiConnect('my-secret-key');

// No need to include the apiKey anymore
api.getData('http://www.example.com/get-endpoint');
api.postData('http://www.example.com/post-endpoint', { name: 'Joe' });
```

# Conclusion

And there you have it! Hopefully by now you see that functions in JavaScript are truly first-class and how important functions can be to your JavaScript development career. I recommend practicing all sorts of ways to use functions in your code!