Skip to content

Closures and Currying in Javascript

Posted on:December 8, 2023 at 02:05 AM

Table of contents

Open Table of contents

Closure

What is closure in javascript ?

definition of closure

When a function returns an another function, it will not only return function, it also returns function scopes with it.

function outer() {
  const count = 0;
  return function inner() {
    console.log(count);
    return count;
  };
}

const res = outer(); // calling outer will return inner function
res(); // it will give you count value 0

Now let’s understand how we can able to remember count value even after calling res or inner function

function outer() {
  let count = 0;
  return function inner() {
    return count + 1;
  };
}

const res = outer(); // calling outer will return inner function
const res1 = res(); // it will give you count value 1
const res2 = res(); // it will give you count value 2

Currying functions

You can create curried functions by defining and immediately returning their inner functions in a chain of closures.

But what does that mean?

function sum(a, b) {
  return a + b;
}

// curried function
function curriedSum(a) {
  return function (b) {
    return a + b;
  };
}
curriedSum(10)(20);

you can extends this function by returning one more function. basically ypu are chining closure functions.

function curriedSum(a) {
  return function (b) {
    return function (c) {
      return a + b + c;
    };
  };
}
curriedSum(10)(20)(5);

Examples

Create a currying function that can accept an unlimited number of arguments and returns sum of arguments.

function curriedSum(a) {
  return function (b) {
    if (b) {
      return curriedSum(a + b);
    } else {
      return a;
    }
  };
}

console.log(curriedSum(1)(2)(3)());

another widely asked question is write callable function curriedSum(1, 2)(2)(3)(4,5,6)()

function curriedSum(...args) {
  const sum1 = args.reduce((a, b) => {
    return a + b;
  }, 0);
  return function (...args) {
    const sum2 = args.reduce((a, b) => {
      return a + b;
    }, 0);
    if (sum2) {
      return curriedSum(sum1 + sum2);
    } else {
      return sum1;
    }
  };
}

console.log(curriedSum(1, 2)(2)(3)(4, 5, 6)());

write a callable function joinUnlimited(“1”, “2”)(“3”)(“3”, “4”, “5”)(“6”)() which returns “1_2_3_3_4_5_6”

function joinUnlimited(...args) {
  const a = args.reduce((prevVal, currentVal) => {
    if (prevVal === "") {
      return `${currentVal}`;
    } else {
      return `${prevVal}_${currentVal}`;
    }
  }, "");

  return function (...args) {
    const b = args.reduce((prevVal, currentVal) => {
      if (prevVal === "") {
        return `${currentVal}`;
      } else {
        return `${prevVal}_${currentVal}`;
      }
    }, "");

    if (b) {
      return joinUnlimited(`${a}_${b}`);
    }

    return a;
  };
}