Use Closures for Memory Optimizations in JavaScript (a case study)

Posted on

Beside functions being first class citizens in JavaScript, there are plenty of other features, allowing functions to make an extra mile ride. Closures are one of them.



What is a Closure?

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment)
Mozilla

Let’s take an example:

function adder(a) {
  return function(b) {
    return a + b;
  };
}

let add5 = adder(5);
let add10 = adder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12
Enter fullscreen mode

Exit fullscreen mode

From above code, it’s clear how closures work, and how it remembers the lexical scope, the function was declared within. But how this could be useful, or is it just non-practical questions in JavaScript interviews?

Don’t worry, we have got plenty of applications and usage, of Closures throughout JavaScript ecosystem. Today, the usage we want to discuss is how we can optimize memory usage using Closures. Consider the code below:

function multiply(y){
    let x = Math.pow(10,10);
    return x* y;
}
multiply(25); //250000000000
multiply(45); //450000000000

Enter fullscreen mode

Exit fullscreen mode

It looks very straight forward, right? … No, actually if you notice every time the multiply() function is called, the let x = Math.pow(10,10) is recreated and occupy certain memory, in this case quite a large memory for sure, due to the large numeric value it’s generating.



Bringing in the Closure

What if we make it possible to create let x = Math.pow(10,10); only once, to the extent where it has been repetitive across the multiply() function calls, this is where the Closures come into play. Let’s take a look at the below modified code:

function multiply(){
    let x = Math.pow(10,10);
    return function(y){
        return x* y;
    }
}
let multiplier= multiply();
multiplier(25); //250000000000
multiplier(45); //450000000000
Enter fullscreen mode

Exit fullscreen mode

Here we introduced returning an inner function, which creates a closure, and does not recreate let x = Math.pow(10,10); with each multiplier() call, and hence avoid excess memory leaks. This conveys us, by using Closures we can easily avoid costly memory jobs.

So that’s it for today. Hope you have benefited from this case study, or Do share if you ever faced similar scenarios and what approaches you have followed. Stay tuned for the next JS hack!

Leave a Reply

Your email address will not be published.