DEV Community

Nitin Jadhav
Nitin Jadhav

Posted on

Improve your JavaScript with functional programming

If you want to write your JavaScript code in a better way, one of the most effective techniques is functional programming (FP). It's no difficult than the language itself - don't let anyone else tell you otherwise. This is intended for beginner programmers. This series will have multiple posts.

Use Pure functions

A pure function is one which

  1. Does not access anything else other than provided arguments.
  2. Does not modify anything outside of a function. It may return the calculated value based on arguments. This means that they will always return the same output when provided with the same input.

Example of pure function

const calculateArea = radius => 3.14 * radius * radius;

Use map() instead of for/forEach for array conversions

(you are probably already doing this)

Process and covert an array into a new array using for/forEach

const nums = [1,2,3,4,5,6];
const doubles = [];
for(let i = 0; i < nums.length; i++){
  doubles.push(nums[i] * 2);
}
// nums.forEach(item => doubles.push(item * 2)); // foreach version
console.log(doubles)

Instead, you should be using map() function (which is built-in in JavaScipt)

const nums = [1,2,3,4,5,6];
const doubles = nums.map(item => item * 2);
console.log(doubles)

Why use the map() instead of the above methods?

  • The code is almost human-readable ("map this array to that with function x"), easy to understand
  • It's minimalistic, uses fewer keystrokes, hence fewer potential bugs

Use reduce() instead of for loop for additive calculations

If you want to calculate something which depends on every value of array, use reduce() function. e.g. you need to add up every element of an array.

for/forEach method:

const array1 = [1, 2, 3, 4];
let sum = 0;
for(let i=0; i< array1.length; i++){
  sum+=array1[i];
}
// array1.forEach(item => sum+= item); //forEach version

// 1 + 2 + 3 + 4
console.log(sum);
const array1 = [1, 2, 3, 4];
const sum = array1.reduce((sum, current) => sum+current, 0);

// 1 + 2 + 3 + 4
console.log(sum);

Why use the reduce() instead of the above methods?

  • less boilerplater than for loop
  • A common construct, much cleaner to read
  • can be chained with other array functions like map: array1.map(i => i*2).reduce((sum, current) => sum+current)

use filter() method for array filter operations:

Filtering array with for loop for even numbers:

const array1 = [1, 2, 3, 4];

const evenArray1 = [];
for(let i = 0; i<array1.length; i++){
  if(array1[i] % 2 === 0){
    evenArray1.push(array1[i]); //copy only even elements
  }
}
console.log(evenArray1);

User filter() method instead:

const array1 = [1, 2, 3, 4];

const evenArray1 = array1.filter(item => item % 2 === 0);
console.log(evenArray1);

Use every() and some() insted of manual search with for loops

Checking if all items in an array satisfy certain criteria (even)

const array1 = [2,4,8];

let isAllEven = true;
for(let i = 0; i<array1.length; i++){
  if(array1[i] % 2 !== 0){
    isAllEven = false;
    break;
  }
}
console.log(isAllEven);

Use every() for the same:

const array1 = [2,4,8, 3];

let isAllEven = array1.every(item => item % 2 === 0)
console.log(isAllEven);

Checking if at least one item in an array satisfy certain criteria (even)

const array1 = [1, 3];

let isAtleastOneEven = false;
for(let i = 0; i<array1.length; i++){
  if(array1[i] % 2 === 0){
    isAtleastOneEven = true;
    break;
  }
}
console.log(isAtleastOneEven);

Use some() for the same:

const array1 = [1, 2, 3];

let isAtleastOneEven =  array1.some(item => item % 2 ===0)
console.log(isAtleastOneEven);

Use Partial functions to create new functions from existing functions using bind()

You can derive new functions from existing functions. E.g. you have a power function that calculates power of number.

const power = (p, num) => num ** p;

you can create a new function square() and cube() that uses existing function

const square = power.bind(null, 2);
const cube = power.bind(null, 3);

console.log(square(5))  // 25
console.log(cube(5))  // 125

Note on performance: Note that for loops are always faster than map() and other similar functions. For a small number of items, say up to a few hundred - both will have similar performance but for a large number of items, you may want to consider for loops.

In the next article, we will discuss some of the advanced functional programming concepts. Thanks!

Top comments (7)

Collapse
 
romstar profile image
Rami • Edited

For loops are faster than map, filter, and reduce. They always will be since they don't have the overhead of call backs. Correct your post at the beginning

"it's faster than the other version" needs to be removed

Collapse
 
nitinja profile image
Nitin Jadhav

You are correct, Thanks. I have updated the article to reflect the same and added a footnote for performance.

Collapse
 
greg profile image
greg

Why const square = power.bind(null, 2) over const square = num => power(2, num)?

Collapse
 
nitinja profile image
Nitin Jadhav

I believe they are doing the same thing. bind() offers a built-in solution for writing a wrapper function, but with the added advantage of passing context as the first argument (which I haven't used here).

Collapse
 
josephthecoder profile image
Joseph Stevens

Functional Programming every time, all the time baby. 💯💯💯

Collapse
 
theodesp profile image
Theofanis Despoudis

One note:

function calculateArea = (radius) => 3.14 * radious * radius;is not valid javascript

Collapse
 
nitinja profile image
Nitin Jadhav

Thanks, corrected!