2

I found this example in Mozilla developers page, but can't understand the concept.

   function outside(x) {
       function inside(y) {
          return x + y;
       }
       return inside;
    }
    fn_inside = outside(3); //returns inside(y) -- from firebug
    result = fn_inside(5); // returns 8

    result1 = outside(3)(5); // returns 8

It seems like 3 is somewhat stored in the function 'inside' and during the second call adds it with 5 and returned 8.

And how does the second call to outside (outside(3)(5)) returned value (8) instead of the inner function (inside) unlike the first call?

user2864740
  • 60,010
  • 15
  • 145
  • 220
Bere
  • 1,627
  • 2
  • 16
  • 22
  • 1
    @elclanrs Maybe. But I don't even see what problem OP has here... It might be *"How can functions be stored in variables ?"* or *"How variables work ?"*... – Denys Séguret Feb 26 '14 at 08:30

2 Answers2

3

It seems like 3 is somewhat stored in the function 'inside' and during the second call adds it with 5 and returned 8.

Right. Each call to outside creates a new inside function, and that function has the data from the call to outside bound to it. It "closes over" that data. These are called "closures." Don't let the name bother you, closures are not complicated.

And how does the second call to outside (outside(3)(5)) returned value (8) instead of the inner function (inside) unlike the first call?

The second call to outside does return a function (the inside function generated by that call); but then you're calling that function immediately with the second pair of ().

The line

outside(3)(5);

...breaks down like this:

var f = outside(3); // Create and get the `inside` function bound to 3
f(5);               // Call it, passing in `5`

From your comment:

So what you mean is, in the first call of outside(3), the 'returned' inside method definition becomes(is changed to?) return 3 + y;. is that right?

Close, but not quite. The value of x isn't burned into inside; inside has a reference to the context in which it was created, and that context gives it access to the x argument. Those aren't quite the same thing, as we can see if we update the example a bit (and ditch the math, which just obscures things):

function outside(name) {
    // 'inside' uses the 'name' argument from the call to 'outside' that created it
    function inside() {
        return name;
    }

    // 'changer' *changes* the 'name' argument's value
    function makeCaps() {
        name = name.toUpperCase();
    }

    // Return both of them
    return {
        inside: inside,
        makeCaps: makeCaps
    };
}

var funcs = outside("foo");
funcs.inside();      // "foo", because 'inside' uses the 'name' created
                     // by the call to 'outside', and that 'name' is
                     // currently "foo"
funcs.makeCaps();    // Changes that same 'name'
funcs.inside();      // "FOO", because that 'name' has been changed

It's key to understand that both inside and changer close over the same context, which is the context of the call to outside that created them.

It's also key to understand that a new context and new functions are created by every call to outside:

var funcs1 = outside("foo");
var funcs2 = outside("separate");
funcs1.inside();     // "foo"
funcs2.inside();     // "separate"
funcs1.makeCaps();
funcs1.inside();     // "FOO"
funcs2.inside();     // "separate"
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks Crowder. It's a bit clearer now. So what you mean is, in the first call of `outside(3)`, the 'returned' inside method definition becomes(is changed to?) `return 3 + y;`. is that right? – Bere Feb 26 '14 at 08:52
  • @Bere: Close, but not quite; I've added further explanation above. – T.J. Crowder Feb 26 '14 at 09:08
  • I almost understand the concept. One last question: I thought that after for e.g. outside("foo") is called, it is gone and its memory is reclaimed ..., no traces of it - except for the values it returned. But from your answer I understand that by keeping its inner functions, we can in effect preserve the outside function's 'context'(variables...). Does it? – Bere Feb 26 '14 at 09:19
  • thanks! (Got answer for may last question http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Bere Feb 26 '14 at 09:39
  • @Bere: Exactly. When you call a function, a context is created. When the function returns, if nothing survives that references the context, that context can be cleaned up (garbage collected). But in this case, because those functions have references to the context, and `outer` returns references to those functions, the context can't be cleaned up. Think of it as an object, and the function objects having a property referring to that object. (In fact, that's basically what it is per the spec; I've simplified a bit, but that's the essence of it.) – T.J. Crowder Feb 26 '14 at 09:39
0

Your variable 'X' is in outside function's scope as well as your inside function. So when you call outside func it creates new function inside and as well stores your variable X, then , when the call to inside function is executed you already have X and just get the Y from it's args.

Y.Puzyrenko
  • 2,166
  • 1
  • 15
  • 23