0

I've been trying to understand how closures in JavaScript work, but I've been having some problems understanding some parts of it.

Let's see this example:

const Component = () => {
    let counter = 0;
    
    const logger = () => {
        console.log(counter);
    }

    setTimeout(() => counter = counter + 10, 1000);

    return logger;
}

const myLogger = Component();

myLogger(); // output after ~1s: 10

When a "closure" is created, the variables that the logger function references (which are not part of the function, and in this case: counter), are stored in the function's hidden [[Scope]] property, so that the function can reference them when it is executed.

I thought that the [[Scope]] property had a copy of the initial values that the function references because it is a lexical scope. But after executing my code, I realized that the value of counter changes way after the function is created. I thought that the value of counter should be 0 after calling myLogger(), because it is the initial value that is stored in the function's scope and can only be changed from within the function.

The setTimeout operation shouldn't increase the counter that is inside of logger. Or at least that's what I thought.

Did I get something wrong or am I missing something else?

Ivan
  • 34,531
  • 8
  • 55
  • 100
Raul
  • 515
  • 1
  • 6
  • 13
  • 1
    It doesn't store a copy of the value, it stores a reference to the variable binding itself. This allows multiple closures in the same scope to share the variable, and a closure that updates the value will affect another closure that reads the value. – Barmar Aug 10 '21 at 17:08
  • This is how closures work in practically all languages, and is what makes them so useful. – Barmar Aug 10 '21 at 17:09
  • The `[[Scopes]]` property is not really something standard to the language. – MinusFour Aug 10 '21 at 17:12
  • But how does that variable get stored into memory? After `Component` reaches the `return` statement, that execution context is deleted (Including its local memory). So, in what memory is that value stored? – Raul Aug 10 '21 at 17:59
  • @Anonymous It's kept on the heap. The execution context memory is not deleted if it is still referenced - classical garbage collection. Variables that are closed over are usually not put on the stack in the first place (although that's an implementation detail of the respective engine, and subject to complicated optimisations). – Bergi Aug 12 '21 at 09:28

0 Answers0