Pure Function In JavaScript

What is Pure Function?

There are 2 simple rules for a function to be a Pure Function.

1. There will be always the same output for the same input.
2. There will be no side effects.

Let's see a code.

const add = (a,b) => a + b;

add(1,2); // 3

Here the add function is a pure function.
Because this function will take any 2 arguments a and b and it will give the same result for that argument which is always a + b.

Let's see another code,

let user = {
    firstName: "Michael",
    lastName: "Jackson",
    gender: "M"
}

function getFullName(user) {
    return `${user.firstName} ${user.lastName}`;
}
console.log(getFullName(user)); // Michael Jackson

In the code snippet getFullName is a pure function, because getFullName is not mutating the state.

what is Impure Function?

1. Create/update database.
2. http/s call.
3. Change the file system.
4. Mutate the state.
etc
Math.random();

Math.random() is an impure function because it always returns a different output.

So is the console.log is a pure function, it returns undefined for any input.

No. console.log is not a pure function because it has side effects, console.log is using another share environment to log into the console.

const add = function (a,b){
    console.log("added");
    return a + b;
} 

add(1,2); // 3

We can see from the above code snippet, we are getting the same output for the same input, and console.log is not effecting our output, then it is not a pure function. Because the add function has a side effect.

let user = {
    firstName: "Michael",
    lastName: "Jackson",
    gender: "M"
}

function getFullName(user) {
    user.firstName = user.gender === "M" ? `Mr. ${user.firstName}`: `Mrs. ${user.firstName}`;
    return `${user.firstName} ${user.lastName}`;
}
console.log(getFullName(user)); // Mr. Michael Jackson

Here in the code snippet getFullName is an impure function, because getFullName is mutating the state. Inside the function definition we are assigning a value to the object property.

Pure vs Impure

Impure function mutates the external state.

let cart = {
    items: [{
        name: "X",
        price: 10,
        quantity: 1
    }]
}

function addItem(cart){
    let newCart = {...cart}
    newCart.items.push({
        name: "Y",
        price: 5,
        quantity: 2
    });
    return newCart;
}
console.log(cart); // {items: Array(1)}

let newCart = addItem(cart); // changing state

console.log(cart); // {items: Array(2)}
console.log(newCart); // {items: Array(2)}

Pure function does not mutate external state. We can make the above function pure by making a little change.

let cart = {
    items: [{
        name: "X",
        price: 10,
        quantity: 1
    }]
}

function deepClone(value){
  return JSON.parse(JSON.stringify(value)); // for example purpose
}

function addItem(cart){
    let newCart = deepClone(cart);
    newCart.items.push({
        name: "Y",
        price: 5,
        quantity: 2
    });
    return newCart;
}
console.log(cart); // {items: Array(1)}

let newCart = addItem(cart); // changing state

console.log(cart); // {items: Array(1)}
console.log(newCart); // {items: Array(2)}

In the snippet we can see, the pure function does not change the cart, instead it is making a copy of the cart and sending as a return value. Due to this the original card is not being changed.

If you are using react, redux then you will see the use of pure function.

Pure function can be easily predicted, it is convenient to test. Pure function makes state management easier.

26