How do JavaScript closures handle variables?

closures, javascript

Solution

A better description than using private bubbles would be that each function keeps a reference to the scope in which it was defined.

It must be clear that it is a reference and not a copy.

This explains that both innerFunctions points to the same scope, and thus the same set of variables. And those variables can also be changed in the external scope or through any of the functions pointing to this scope.

As a complementary remark : a scope in JavaScript is created each time you call a function (there are also other scopes, most notably the global scope but also the ones you can create with `with` or `try/catch`).

Problem

Suppose we have a `containerFunction` with two functions defined within it: ``` var innerFunction1link; var innerFunction2link; function containerFunction() { var someInnerVariable = 1; innerFunction1link = innerFunction1; innerFunction2link = innerFunction2; function innerFunction1() { console.log("I'm 1 " + someOuterVariable + " " + (someInnerVariable++)); } function innerFunction2() { console.log("I'm 2 " + someOuterVariable + " " + (someInnerVariable++)); } } containerFunction(); var someOuterVariable = 42; // Point A innerFunction1link(); innerFunction2link(); someOuterVariable = "WAT?!"; // Point B innerFunction1link(); innerFunction2link(); ``` Now the question. According to "Secrets of The JavaScript Ninja" book, each closure will have its own private set of variables (including the ones defined later, like `someOuterVariable`): So `innerFunction1` and `innerFunction2` referenced outside of `containerFunction` as `innerFunction1link` and `innerFunction2link` will have their "private bubbles" with full set of variables in them. At the "Point A" both functions will execute fine and will output: ``` I'm 1 42 1 I'm 2 42 2 ``` Then, when I set `someOuterVariable` to `"WAT?!"`, the output is: ``` I'm 1 WAT?! 3 I'm 2 WAT?! 4 ``` How will value of `someOuterVariable` and `someInnerValue` be actually updated in both "private bubbles" (and what if there were 1000 of those bubbles)? Does it actually keep track of all the references to all variables? And if one closure updates `someOuterVariable`, how its value will be populated to other closure? Update: And even if `innerFunction`'s will be defined in different contexts, they will still "share" variables: ``` function containerFunction1() { var someInnerVariable = 1; innerFunction1link = innerFunction1; function innerFunction1() { console.log("I'm 1 " + someOuterVariable + " " + (someInnerVariable++)); } } function containerFunction2() { var someInnerVariable = 1; innerFunction2link = innerFunction2; function innerFunction2() { console.log("I'm 2 " + someOuterVariable + " " + (someInnerVariable++)); } } containerFunction1(); containerFunction2(); var someOuterVariable = 42; innerFunction1link(); innerFunction2link(); someOuterVariable = "WAT?!"; innerFunction1link(); innerFunction2link(); ``` Output: ``` I'm 1 42 1 I'm 2 42 1 I'm 1 WAT?! 2 I'm 2 WAT?! 2 ```

Original source