Closure my spending

Published 3 months ago

A closure in JavaScript is a feature which allows an inner function to access variables within its own scope, within its outer functions scope and within the global scope.

Let's create a simple money spending tracker utilising this powerful feature

function trackSpending() {
  let totalSpend = 0;

  return function handlePurchase(purchaseAmount) {
    return (totalSpend += purchaseAmount);
  };
}

We declare a function named trackSpending which returns another function handlePurchase. So if we call trackSpending the returned value will be a function. Let's do that...

const andysSpending = trackSpending();

Okay, so now the constant andysSpending is actually a function that can be called. Can you see how the returned function from trackSpending uses the let totalSpend in its return value? That is closure, as we are accessing a variable in an outer scope.

Let's buy a couple of pints of Guinness...

andysSpending(3.5); // 3.50
andysSpending(3.5); // 7.00

Can you see how our totalSpend is increasing with every purchase? Perfect! When andysSpending was "born" it was given a backpack of data, in our case totalSpend. We can manipulate this throughout the lifetime of andysSpending.

With all this spending I think we need to set a spending limit! We can use default parameters to set a spending limit if an argument isn't passed in.

function trackSpending(spendingLimit = 100) {
  let totalSpend = 0;

  return function handlePurchase(purchaseAmount) {
    let maxSpend = spendingLimit;

    if (totalSpend + purchaseAmount > maxSpend) {
      return "Cannot let you purchase as you will exceed your spending limit";
    }

    return (totalSpend += purchaseAmount);
  };
}

We will need to go back and pass in our spending limit. I don't want to spend more than ten bits of currency today.

const andysSpending = trackSpending(10);

Right, I've already spent 7 of whatever currency I'm using. I'll try and spend over my limit...

andysSpending(3.5); // Cannot let you purchase as you will exceed your spending limit

And that is a very simple use case utilising closure in JavaScript. You could improve this by returning a list of what has been purchased too!

function trackSpending(spendingLimit = 100) {
  let totalSpend = 0;

  return function handlePurchase(purchaseAmount) {
    let maxSpend = spendingLimit;

    if (!purchaseAmount) {
      return "You grabbed a freebie, nice! Or maybe you stole it?";
    }

    if (totalSpend + purchaseAmount > maxSpend) {
      return "Cannot let you purchase as you will exceed spending limit";
    }

    return (totalSpend += purchaseAmount);
  };
}