Functional JavaScript — Closures
Tags: webdev, programming, javascript, functional
Published: 2021-01-25 01:31:29

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to use closures.

### Closures

Closures are inner functions.

An inner function is a function within a function.

For example, it’s something like:

```
function outer() {
  function inner() {}
}
```

Closures have access to 3 scopes.

They include variables that are declared in its own declaration.

Also, they have access to global variables.

And they have access to an outer function’s variable.

For example, if we have:

```
function outer() {
  function inner() {
    let x = 1;
    console.log(x);
  }
  inner();
}
```

then the console log logs 1 because we have `x` inside the `inner` function and we access it in the same function in the console log.

The `inner` function won’t be visible outside the `outer` function.

We can also access global variables within the `inner` function.

For example, if we have:

```
let global = "foo";

function outer() {
  function inner() {
    let a = 5;
    console.log(global)
  }
  inner()
}
```

Then `'foo'` is logged since `inner` has access to the `global` variable.

Another scope that `inner` has access to is the scope of the `outer` function.

For example, we can write:

```
function outer() {
  let outer = "outer"

  function inner() {
    let a = 5;
    console.log(outer);
  }
  inner()
}
```

We have the `outer` variable and we access it in the `inner` function.

### Closure Remembers its Context

A closure remembers its context.

So if we use it anywhere, the variables that are in the function are whatever they are within the original context.

For example, if we have:

```
const fn = (arg) => {
  let outer = "outer"
  let innerFn = () => {
    console.log(outer)
    console.log(arg)
  }
  return innerFn;
}
```

Then the `outer` and `arg` variable values will be the same regardless of where it’s called.

`outer` is `'outer'` and `arg` is whatever we passed in.

Since we return `innerFn` with `fn` , we can call `fn` and assign the returned function to a variable and call it:

```
const foo = fn('foo');
foo()
```

We pass in `'foo'` as the value of `arg` .

Therefore, we get:

```
outer
foo
```

from the console log.

We can see that the values are the same even if we called it outside the `fn` function.

### Real-World Examples

We can create our own `tap` function to let us log values for debugging.

For example, we can write:

```
const tap = (value) =>
  (fn) => {
    typeof(fn) === 'function' && fn(value);
    console.log(value);
  }

tap("foo")((it) => console.log('value:', it))
```

to create our `tap` function and call it.

We have a function that takes a `value` and then returns a function that takes a function `fn` and runs it along with the console log.

This way, we can pass in a value and a function.

Then we get:

```
value: foo
foo
```

logged.

The first is from the callback we passed in.

And the 2nd is from the function we returned with `tap` .

### Conclusion

Closures are inner functions.

They have access to the outer function’s scope, global variables, and their own scope.

We can use it or various applications.