Utku
Utku

Reputation: 2187

Why isn't the following JavaScript function a closure?

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?

Upvotes: 1

Views: 65

Answers (2)

Bergi
Bergi

Reputation: 665574

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.

Upvotes: 2

basav
basav

Reputation: 1495

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.

Upvotes: 0

Related Questions