Functional JavaScript — Useful Higher-Order Functions

John Au-Yeung - Jan 25 '21 - - Dev Community

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 to create our own higher-order functions.

unary Function

We can create our own unary function that returns a function that only calls one argument.

For example, we can write:

const unary = (fn) =>
  fn.length === 1 ?
  fn :
  (arg) => fn(arg)
Enter fullscreen mode Exit fullscreen mode

We have the fn which is a function.

We check the length property of fn , which returns how many parameters it has.

If it only has one parameter, then we return the fn function.

Otherwise, we return a function that calls fn with only one argument.

This way, we can use functions like parseInt with the map method safely.

For example, we can write:

const nums = ['1', '2', '3'].map(unary(parseInt));
Enter fullscreen mode Exit fullscreen mode

We call the unary function with parseInt so that we can use the callback withn only of parameter to parse the string to an integer.

parseInt takes the value to parse, and the radix as the second argument, so we can’t just pass parseInt straight to map because the radix will be the index of the array entry, which isn’t what we want.

With our unary function, we always call parseInt with only the value passed in.

Therefore, nums is [1, 2, 3] .

once Function

We can create a once function to only call a function once.

For example, we can write:

const once = (fn) => {
  let done = false;
  return function(...args) {
    if (!done) {
      done = true;
      fn.apply(this, args);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

We have the once function, which only runs the fn function that’s passed in when done is false .

If that’s the case, then we set done to true and call fn with apply .

apply takes the this value as the first argument and the array of arguments as the 2nd argument.

Then we can use it to only call a function once by writing:

const foo = once(() => {
  console.log("foo")
})

foo();
foo();
Enter fullscreen mode Exit fullscreen mode

We call the once function with a function that we only want to call only once.

Then we can call it twice and see that 'foo' is only logged once.

Memoize

We can cache the return value of our function call by creating our own memoize function.

For example, we can write:

const memoize = (fn) => {
  const cache = {};
  return (arg) => {
    if (!cache[arg]) {
      cache[arg] = fn(arg);
    }
    return cache[arg]
  }
}
Enter fullscreen mode Exit fullscreen mode

We created a memoize function that takes the fn function.

In the function, we define the cache object.

And we return a function that takes the arg argument.

We check if cache[arg] is in the cache.

If it’s not, then we set the value in the cache object.

And then we return the cached value.

Then we can use it by writing:

let fastFib = memoize((n) => {
  if (n === 0 || n === 1) {
    return 1;
  }
  return n + fastFib(n - 1);
});
Enter fullscreen mode Exit fullscreen mode

We pass in our Fibonacci function to return the Fibonacci number given the value of n .

This is much faster since we can look up the past computed values from the cache object.

Conclusion

We can create our own higher-order functions to do various things with it.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .