Closure Example Question

Hi, I’ve been reading about closures and came across these two examples:
Example 1:

function add() {
  let counter = 0;
  counter += 1;
  return counter;
}
console.log(add());
console.log(add());
console.log(add());
// returns 1 1 1

Example 2:

const add = (function () {
  let counter = 0;
  return function () {counter += 1; return counter};
})();
console.log(add());
console.log(add());
console.log(add());
// returns 1 2 3

Why isn’t the second example returning 1 1 1 like the first? Is it not resetting the counter each time it’s called?

Thanks

In the second example, add is the function that is returned:

function () {
  counter += 1; 
  return counter;
}

This function has access to the counter variable that was initialized in the IIFE. The IIFE only sets counter to 0 one time. This is the power of closure. You can access variables from functions that have already been called an no longer in use. The “closed” variables remain accessible in the functions they are returned in.

1 Like

Thanks for answering. So, when add() is first called it runs the whole function, but each additional time it’s called, it goes straight to the return statement, so the counter doesn’t reset to 0 (This seems to be the case because I also added console.log('counter: ’ + counter); below the counter declaration, and it only runs that the first time add() is called as well). Do I have that right?

Also, does the add() function need to be an IIFE for this to work this way?

Thanks!

Not quite.

The result of the IIFE is assigned to add. The result happens to be a function that “know” the value of counter that was created in the IIFE. When add is called each time, the value of counter is incremented and returned.

No, you could do also write it something like below to achieve the same result:

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

const add = counter();

console.log(add());
console.log(add());
console.log(add());
1 Like

Thanks for responding again. I’m still not getting what’s happening each time we console.log(add()) after the first. From what I understand, the nested function holds onto the counter variable after the IIFE is finished running, so counter keeps its value (since it’s not being reset by the function each additional time it’s run). I just don’t get exactly why the counter isn’t being reset and the console.log I added isn’t being displayed, each additional time it runs. Does the IIFE run only once and then only the nested function runs each additional time? Sorry I’m not getting it. Thanks for your patience

Yes.

The nested function is what actually gets assigned to the add variable, because that is what executing the IIFE returns. The IIFE just is a shorter way of writing what I wrote in the last reply. When you call add, it is only running the following code:

count += 1; return count

The code above was in an anonymous function that was originally nested inside the IIFE, but once the IIFE ran, the code is part of the add function forever more.

1 Like

Got it! Thanks for your time!