1

var x = 5;

function f0() {
    return function () {
 var y = 10;
 var z = x + y;
 console.log('x + y is: ' + z);
    }
}

var myFunc = f0();

myFunc();

x = 10;

myFunc();

In the example above, I expected x + y is: 15 to be printed in the second time as well. Because, to the best of my knowledge, what is returned from f0 is a closure. I thought that a closure takes a snapshot of the variables at its environment at the time it is defined. Hence, I thought that changing x with x = 10; wouldn't affect the free variables used in a closure.

But apparently I was wrong. Could you tell me why does changing x change the result of the function which is returned from f0?

  • Is it because what is returned from f0 is not a closure?
  • Is it because a closure does not record the values of the variables at the scope it is being returned to?
  • Is it because of another reason?
Utku
  • 2,025
  • 22
  • 42
  • 2
    maybe you want to have a look at this Q/A first : http://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript – Tom Dec 11 '16 at 12:52
  • 1
    Also refer to this most voted question on SO tagged Javascript (about closures): http://stackoverflow.com/q/111102/3946520 – kumardeepakr3 Dec 11 '16 at 13:23
  • 3
    No, it does not "take a snapshot". Where did you get that idea? –  Dec 11 '16 at 13:46

2 Answers2

2

Is it because what is returned from f0 is not a closure?

No. Every function is a closure in JavaScript.

Is it because a closure does not record the values of the variables at the scope it is being returned to?

Yes. A closure does not record the values, taking a snapshot of the current state. It simply does record the reference to the scope. And it's the scope it was defined in, not the scope it is returned to.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • The upper scope still exists because there is a closure that references to it, right? Does that mean if I create multiple closures with `var myFunc1 = f0();`, `var myFunc2 = f0();` etc., then does that mean the scope is duplicated for every closure? – Utku Dec 11 '16 at 15:18
  • Yes, exactly, every `f0()` function call creates a scope which the respective closure(s) will retain. Though in your example, there actually aren't any variables in that `f0` scope, it's the global scope with the `var x` (which is later modified) that is closed over. – Bergi Dec 11 '16 at 15:26
0

I am going to digress a little bit in the beginning to get concept of closures clear. In a language like c++, it is considered a bad idea for a function to return local variables, unless they are allocated on heap.

example:

 x foo() {
   x obj;
   return obj;
 }

 cout<< foo() << endl;

In above example, obj would be destroyed as soon as we return from foo, and hence, we end up getting garbage as output.

In Javascript, that would be legal, due to the concept of closures.

A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.

So, in your case, one variable(y) would be from environment of enclosing function, but x is a global variable, and can be changed from outside function.

The inner enclosing variables(such as y) are also called private variables, since the only way to get to them would be through myFunc() in your case.

basav
  • 1,475
  • 12
  • 20