-2

I was going through the closures definition in Mozilla and found this example -

function makeSizer(size) {
  return function () {
    document.body.style.fontSize = `${size}px`;
  };
}

const size12 = makeSizer(12);
const size14 = makeSizer(14);
const size16 = makeSizer(16);

What I still don't understand is that if I want to increase the font, I can still do it this way -

function makeSizer(size) {
  document.body.style.fontSize = `${size}px`;
}

const size12 = makeSizer(12);
const size14 = makeSizer(14);
const size16 = makeSizer(16);

What is the concept of closures doing here? Why the extra inner function? Please correct my understanding.

beta programmers
  • 513
  • 2
  • 8
  • 23
  • With your code, `size12` and the others are all `undefined`. The closure code assigns the returned functions to those variables, `size12()` can be run over and over again. (I acknowledge that it's not the most interesting example.) – Pointy Mar 11 '23 at 14:01
  • 1
    The first one return the inner function (unexecuted) to the variable. then you can do `size12()` to run it. – Louys Patrice Bessette Mar 11 '23 at 14:02
  • Better examples would perhaps mention Array methods like `.filter()` and `.map()`, which take functions as arguments. A "function maker" function like your sample from MDN can make those functions, so that different situations calling for different `filter()` callbacks can easily be accomodated by making new filter callback functions. – Pointy Mar 11 '23 at 14:07

2 Answers2

3

The difference is that in the first code block, makeSizer creates and returns a function that hasn't yet been called. If you call it, it will apply the given size to the element. (And if you don't call it, it won't.) In contrast, your rewrite supplies the size to use directly and does the work immediately.

I think it may be clearer if we use the classic example, which is a bit simpler (see comments):

function makeAdder(addend) {
    return function (value) {
        return value + addend;
    };
}

// Let's make a function that will add 6 to whatever value we give it
const add6 = makeAdder(6);

// At this point, we haven't *called* the adder, we've just created it

// Let's call it:
console.log(add6(7));   // 13
console.log(add6(2));   // 8
console.log(add6(36));  // 42

This related question's answers may also be useful: How do JavaScript closures work?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

The function closures the size variable, so when you call the returned function the value of size will be the same as you gave it to the makeSizer function. Without closuring, makeSizer returns undefined and cannot be reused.

function makeSizerClosure(size) {
    return function () {
        document.body.style.fontSize = `${size}px`
    }
}

const size12c = makeSizerClosure(12)
const size14c = makeSizerClosure(14)
const size16c = makeSizerClosure(16)

size12c() // size12c sets fontSize to 12, cause it knows the size value as it's closured

function makeSizer(size) {
    document.body.style.fontSize = `${size}px`
}

const size12 = makeSizer(12)
const size14 = makeSizer(14)
const size16 = makeSizer(16)

// you can't even run it cause it's undefined
size12() // error: size12 is not a function
j-0-n-e-z
  • 313
  • 1
  • 9