📖
Maissen's Grimoire
  • Maissen's Grimoire
  • Html and css grimoire
    • HTML5 Periodical Table
    • HTML Cheat Sheet
    • CSS Cheatsheets
  • Javascript Grimoire
    • JavaScript Cheat Sheet
      • Javascript Array in depth
      • Tagged Template Literals
      • Guard Clauses - The Best Way To Write Complex Conditional Logic
      • JavaScript Optional Chaining
      • JavaScript Null Coalesce
      • What Are Magic Numbers And Why Are They Bad
      • ES6/ECMAScript2015 Cheatsheet
      • First-class and Higher Order Functions: Effective Functional JavaScript
    • Useful JavaScript Tips, Tricks and Best Practices
    • Bits of code
    • Useful JavaScript libraries
      • Components
      • Animation
      • Maps
      • Helpers
      • Presentations
      • Charts
      • Games
      • Audio
      • Images
      • Video
    • Js the right way
  • Angular Grimoire
    • Angular doc
    • Getting Started
    • Angular clean architecture
    • Angular Cheat Sheet
    • TypeScript Cheat Sheet
    • My Favorite Tips and Tricks in Angular
    • NgRx: tips & tricks
    • Bits of code
      • Execute Multiple HTTP Requests in Angular
      • Authentification
        • Angular 8 JWT Authentication with HttpInterceptor and Router
      • Integrations
        • Spring Boot
          • Rest Example
            • Angular,Spring Boot,Spring Data and Rest Example(CRUD)
          • Authentification
            • Angular, Spring Boot: JWT Authentication with Spring Security example
            • Angular Spring Boot Security Oauth2
              • Spring Boot OAUTH2 Role-Based Authorization
              • Spring Boot Security Google Oauth
              • Spring Security OAuth2 User Registration
    • Most used dependency
  • Node Grimoire
    • Express.js 4 Cheatsheet
    • Useful Dependencies
    • How To Use And Write Express Middleware
    • Node.js with SQL databases
      • Node.js Token Based Authentication & Authorization example
      • Node.js Rest APIs example with Express, Sequelize & MySQL
      • Node.js Express & PostgreSQL: CRUD Rest APIs example with Sequelize
      • Sequelize
        • Sequelize Many-to-Many Association example – Node.js & MySQL
        • Sequelize One-to-Many Association example with Node.js & MySQL
    • Node.js with NOSQL databases
      • Node.js + MongoDB: User Authentication & Authorization with JWT
      • Node.js, Express & MongoDb: Build a CRUD Rest Api example
      • MongoDB One-to-One relationship tutorial with Mongoose example
      • MongoDB One-to-Many Relationship tutorial with Mongoose examples
      • MongoDB Many-to-Many Relationship with Mongoose examples
  • Upload files
    • How to upload multiple files in Node.js
    • Upload & resize multiple images in Node.js using Express, Multer, Sharp
    • Upload/store images in MySQL using Node.js, Express & Multer
    • How to upload/store images in MongoDB using Node.js, Express & Multer
  • React Grimoire
    • React Doc
    • React Grimoire
    • React Cheat Sheet
  • spring boot Grimoire
    • Getting started
    • Spring Boot, Spring Data JPA – Rest CRUD API example
    • Spring Boot Token based Authentication with Spring Security & JWT
  • Mongo Grimoire
    • MongoDb-Mongoose Cheat Sheet
  • Development tools
    • Design Patterns
  • maissen_grimoire
Powered by GitBook
On this page
  • Functions: the killer JavaScript feature we never talk about.
  • First-class functions
  • First-class functions in practice
  • Cheap dependency injection
  • Callbacks and non-blocking IO
  • More functional programming primitives that require first-class functions
  • Higher order functions
  • Array#map
  • Array#filter
  • Array#reduce
  • Higher order functions in practice
  • No more loops
  • Side-effect free programming
  • Declarative Code Optimisations
  • Effective Functional JavaScript

Was this helpful?

  1. Javascript Grimoire
  2. JavaScript Cheat Sheet

First-class and Higher Order Functions: Effective Functional JavaScript

PreviousES6/ECMAScript2015 CheatsheetNextUseful JavaScript Tips, Tricks and Best Practices

Last updated 5 years ago

Was this helpful?

Functions: the killer JavaScript feature we never talk about.

JavaScript is a very in-demand language today. It runs in a lot of places from the browser to embedded systems and it brings a non-blocking I/O model that is faster than others for some types of applications. What really sets JavaScript apart from the rest of scripting languages is its highly functional nature.

JavaScript has more in common with functional languages like than with C or Java. — Douglas Crockford in

It’s a widely publicised fact that Brendan Eich, when creating the first version of JavaScript, was actually told he would be able to build a . It turns out that Sun Microsystems had other ideas and this programming language needed to wear a coat of procedural syntax inherited from a C or Java-like language. Despite all the semicolons, at its heart JavaScript remains a functional language with features such as first-class functions and closures.

This post will focus on first-class functions and higher order functions. To read more about closures and how to leverage them to wield JavaScript’s functional powers,

First-class functions

A language with first-class functions means that it treats functions like expressions of any other type. Functions are like any other object.

You can pass them into other functions as parameters:

function runFunction(fn, data) {
  return fn(data);
}

You can assign a function as a value to a variable:

var myFunc = function() {
  // do something
};
const myNewGenFunc = someParam => someParam;

You can return a function:

function takeFirst(f, g) {
   return f;
}

First-class functions in practice

Cheap dependency injection

In languages without first-class functions to pass a dependency in you usually inject an object. Here we can just pass functions around, which is great.

It gets even better with ES6 default parameter syntax.

// in fetch.js
import axios from 'axios';
export function fetchSomething(fetch = axios) {
  return fetch('/get/some/resource');
}
// in someModule.js
import axios from 'axios';
import { fetchSomething } from './fetch';
const fetcherWithHeaders = axios({
  // pass some custom configs
});
fetchSomething(fetcherWithHeaders)
.then(/* do something */)
.catch(/* handle error */);
// in someOtherModule.js
import { fetchSomething } from './fetch';
fetchSomething()
.then(/* do something */)
.catch(/* handle error */);

Callbacks and non-blocking IO

JavaScript’s default behaviour on IO is non-blocking. This means we tend to pass a lot of callbacks (until Promises came along at least). Being able to pass a function as a callback instead of an object on which we will run a method (like we would in say Java) means we can have terseness in callback-based code.

For example in Node:

const fs = require('fs');
fs.readFile('./myFile.txt', 'utf-8', function(err, data) {
  // this is a callback, it gets executed
  // once the file has been read
});

More functional programming primitives that require first-class functions

Being able to return a function and closures means we have access to things like partial application and currying.

It also means we can start creating higher order functions.

Higher order functions

A function is a higher order function if it takes a function as a parameter, or returns a function as its result. Both of these requirements rely on functions being first-class objects in a language.

map, filter and reduce/reduceRightare the functions present in JavaScript that map to classic higher order functions in other functional languages.

In other languages:

  • map tends to be called map or transform

  • filter is called select in some languages

  • reduce and reduceRight are the fold left and right functions (also called accumulate, aggregate, compress or inject in different languages)

In functional programming languages, there are no loops. When you need to do an operation like traversing a list or a tree, there are two predominant styles: recursion and higher order functions.

Higher order functions are usually provided by the language. In ES6 JavaScript these functions are defined on the Array prototype.

Array#map

map is used if we want to perform the same change on each member of the array. It takes the function that should be applied to each element of the array as a parameter. That function is passed (element, index, wholeArray) as parameters.

const myArr = [ 'some text', 'more text', 'final text' ];
const mappedArr = myArr.map( function(str) {
  return str.split(' ');
});
console.log(mappedArr);
// [ [ 'some', 'text' ], [ 'more', 'text' ], [ 'final', 'text' ] ]

Array#filter

filter allows us to pick which elements of the array should remain in the transformed list by passing a filtering function that returns a Boolean value (true/false). As for map this functions is passed (element, index, wholeArray).

const myArr = [ 5, 10, 4, 50, 3 ];
const multiplesOfFive = myArr.filter( function(num) {
  return num % 5 === 0;
});
console.log(multiplesOfFive);
// [ 5, 10, 50 ]

Array#reduce

reduce is used to change the shape of the array. We provide more than 1 parameter to this function (in addition to the array we’re reducing). We pass a reducing function and optionally the initial value of to reduce with. The function is passed (prev, curr, index, wholeArray) . prev is the value returned by the previous reduction, for the first iteration that means it’s either the initial value of the first element of the array. curr is the value in the array at which we’re at.

The classic example is summing or concatenating.

const myNumbers = [ 1, 2, 5 ];
const myWords = [ 'These', 'all', 'form', 'a', 'sentence' ];
const sum = myNumbers.reduce( function(prev, curr) {
  return prev + curr;
}, 0);
console.log(sum); // 8
const sentence = myWords.reduce( (prev, curr) => {
 return prev + ' ' + curr;
}); // the initial value is optional
console.log(sentence);
// 'These all form a sentence'

If you want to learn more about the internal of map, filter and reduce or recursion, I’ve reimplemented them in a recursive style using ES6 destructuring in the following post:

Higher order functions in practice

No more loops

Higher order functions allow us to get rid of the imperative loops that seem to be spread everywhere.

var newArr = [];
var myArr = [ 1, 2, 3 ];
for(var i = 0; i < myArr.length; i++) {
  newArr.push(myArr[i] * 2);
}
console.log(newArr); // [ 2, 4, 6 ]
// nicer with `map`
const doubled = myArr.map( x => x * 2 );
console.log(doubled); // [ 2, 4, 6 ]

The intent is just clearer with map. We can also extract the double function so we’re making our code more readable and modular.

const double = x => x * 2;
const doubled = arr.map(double);

It reads like a book and that’s important because we write for humans not machines.

Side-effect free programming

Array higher order functions do not mutate the variable they are called on. This is good, because the loop-based approach using .push and .pop changes it. It means if you pass a variable as a parameter, it’s not suddenly going to get changed by a function down the call stack.

// some random module
// obviously no one actually does this
function doesBadSideEffect(arr) {
  return arr.pop();
}

// somewhere quite important
var arr = [ 'a', 'b', 'c' ];
var joinedLetters = '';
for(var i = 0; i < arr.length; i++) {
  joinedLetters += arr[i];
  doesBadSideEffect(arr)
}
console.log(joinedLetters);
// whoops 'ab'
// even though the naming makes us
// expect 'abc'

Declarative Code Optimisations

In some languages functions like map are parallelised. That’s because we don’t actually need to know what’s in the rest of the array to compute this particular element’s new value. If we’re doing complex things in the mapping function then this sort of optimisation could be very useful.

Effective Functional JavaScript

Use first-class and higher order functions to write nicer code more easily. It’s nice and declarative instead of imperative, say what you want done not how to do it

This will enable you to compose your functions and write code that is extremely terse without losing readability.

For example in Java to run a custom sort on an ArrayList, we have to use ArrayList#sort which expects a Comparator object as a parameter (see ). In JavaScript we use Array#sort () which expects a function. This is a bit less verbose since in this case we’re just going to be implementing one method of the Comparator interface

Recursion relies on a function calling itself, usually on a different part of the parameter (list being traversed for example). That’s a topic for

the Java API docs here
MDN reference here
another post
Lisp or Scheme
JavaScript: the World’s Most Misunderstood Language
Lisp, a list processing language like Scheme or common Lisp
Recursion in JavaScript with ES6, destructuring and rest/spread | HackerNoonhackernoon
Recursion in JavaScript with ES6, destructuring and rest/spread | HackerNoonhackernoon
Logo
Logo
https://hackernoon.com/ingredients-of-effective-functional-javascript-closures-partial-application-and-currying-66afe055102a
https://hackernoon.com/ingredients-of-effective-functional-javascript-closures-partial-application-and-currying-66afe055102a
Logo
Logo