Trying to understand closure

Hello, I’m not at my desk at the moment so hopefully this post is not too janky.

I am reviewing the YDKJS book (3rd Ed) and I am having trouble understanding one of the examples they gave to explain the concept of closure.

Can someone explain (like I’m a 5 year old) how/why console.log(twice(5)) returns 10.

I’ve read it several times and I am not getting it:

Happy to type it out once I’m back at my desk if it’s not legible in the photo.

Many thanks.

multiplier accept a number and returns a function
the function returned for multiplier(2) is number => number * 2
this function is stored in twice and when you call twice(5), the number 5 is passed in the number parameter so it returns 10

Let’s rewrite that example a bit…

function multiplier(factor) {
  // return a function...
  // this function takes a number and
  // multiplies by factor (a value in the enclosing scope, closure, of the multiplier function
  return function(number) { return number * factor }
}

const multiplyBy2 = multiplier(2)
/*
under the hood multiplyBy2 looks like this.
multiplyBy2(number){
  return number * 2; // factor (is a variable in the closure its value is 2) 
}
*/

const multiplyBy11 = multiplier(11)
/*
under the hood multiplyBy11 looks like this.
multiplyBy2(number){
  return number * 11; // factor (is a variable in the closure its value is 11) 
}
*/

console.log(multiplyBy2(10)); // 20
console.log(multiplyBy11(8)); // 88

Javascript creates those functions and when it is time to run them it will evaluate ‘factor’ to the value that
is in closure (the local enclosing scope)

1 Like

Thanks @milesmeow and @ilenia.

I’m still a little confused though. Following the “under the hood” explanations, what happens under the hood at this stage: console.log(multiplyBy2(10));

This is what I understand happens under the hood:

  1. multiplyBy2 returns number * 2
  2. So then we have console.log((number*2)(10))…?
  3. How does that become console.log(10 * 2)…?

I guess I don’t get how 10 becomes the number parm…?

Thanks!

Oh wait…scratch that. Is this it:

  1. multiplyBy2 returns number => number * 2
  2. So then we have console.log(number(10))
  3. This becomes console.log(10 * 2)

Just for clarification, the example is from Eloquent JavaScript, not YDKJS. Here is the chapter for anyone interested. And here is YDKJS Scope & Closures book as well, just for good measure.

Anyway, you seem to have your answer so I’m guessing there is no need for further explanations.

1 Like

You’re getting really close. I think maybe the thing that’s tripping you up is not understanding that functions can be assigned to variables in JavaScript.

Using @milesmeow 's code, the function multiplier returns a function. The line const multiplyBy2 = multiplier(2) is assigning the function returned from multiplier to the variable named multiplyBy2.

We can now call multiplyBy2 just like any other function, by using (). It also takes one argument, in this case we called it number. So the line multiplyBy2(10), is calling the function multiplyBy2 with the argument number as the value 10.

So the second step you wrote

  1. So then we have console.log(number(10))

should instead be console.log(multiplyBy2(10)) which evaluates down to console.log(10 * 2).

1 Like

So sorry. Yes you are right. I mixed up the two books. Thanks for setting it straight.

This is incorrect. And if you will understand why - you will understand closure :slight_smile:

multiplyBy2 returns number => number * factor, not 2

This would be much greater example of closure in my opinion:

function multiplier(factor) {
  return number => number * factor++;
}

let multiply = multiplier(1);
multiply(5); // 5
multiply(5); // 10
multiply(5); // 15
multiply(5); // 20
2 Likes

Great thread! Thought I knew what was going on but then I got confused. And I realized I’d never seen this before.

Thank you.

Still not sure I understand why/when to use in practice though :thinking:

OK, I think I’m getting it. I’m sure I’m only repeating exactly what has been said before but I need to put it in my own words:

Following the same code as @milesmeow:

function multiplier(factor) {
  return function(number) { return number * factor }
}

const multiplyBy2 = multiplier(2)

multiplyBy2(10)

So - this is how the code would run:

  1. multiplier(2) returns: function(number) {return number * 2}
  2. Therefore, multiplyBy2 = function(number) {return number * 2}
  3. So multiplyBy2(10) just means run the returned function with the argument of 10: function(10) {return 10 * 2}
  4. Final answer: 20
1 Like

You use it constantly when programming JavaScript, you just tend not to notice it because large chunks the way the language works are built upon it so it’s just How Things Work (for example all async stuff and anything that uses callbacks). Most of the examples, like the one that threw OP, are abstract and imo maybe actively make it seem more esoteric and complicated than it actually is. I would say most transparently they are used where objects (class instances) would be used in an OO language (though probably less true since ES2015 and modules & class syntax)

1 Like