0

I was reading the following topic How do JavaScript closures work? and found this code:

function foo(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    alert(x.memb);
  }
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);

The author commented:

As expected, each call to bar(10) will increment x.memb. What might not be expected, is that x is simply referring to the same object as the age variable! After a couple of calls to bar, age.memb will be 2!

I am confused why it will return 2 always. Can you explain me how it will come 2 always?

Community
  • 1
  • 1
Rocky Singh
  • 15,128
  • 29
  • 99
  • 146

4 Answers4

2

What's happening here is that: foo returns a function that, when called, increments the memb property of the object originally passed in to foo.

It would be clearer for that parameter object, age, to be a simple object; but the original author is perhaps having fun here, so passes in a new Number - which, as far a Javascript is concerned, is as valid an object as any.

So when bar is called, the memb property on that Number object is created/incremented.

The "internal value" of that number remains unchanged; it's always 2. But age.memb gets incremented by one each time. That's what the author means by:

After a couple of calls to bar, age.memb will be 2!

The 2 here refers to the value of memb after being incremented a couple of times (ie twice), it's not related to the value of the Number that age just happened to be at the start. Call bar again, and age.memb will be 3.

BrendanMcK
  • 14,252
  • 45
  • 54
0

bar(10) has a reference to foo(2)

So each time you call bar(10). It will execute the inner function(closure) of foo which is having parameter y as 10 and since bar has age reference as 2. So age will be 2 always if you call bar(10) and y will be 10 or so depending on value provide. Closure basically saves the reference to inner function even if the outer function is not there.

Ashirvad
  • 2,367
  • 1
  • 16
  • 20
  • `bar` is a function that has a reference to `age`. It does not have a reference to `foo` or to `foo(2)` (which would be itself). – Jon Aug 21 '12 at 09:45
0

If I understand correctly you obtain some like a function pointer in bar. This points to the nameless function. This nameless function always receives the same input because foo is only called once i.e. x never changes. As a result there is no memory in the nameless function giving you the input value of x as a result always.

Nebula
  • 1,045
  • 2
  • 11
  • 24
0

It will not "always" be 2.

Author says: "After a couple of calls to bar, age.memb will be 2" - and after 2 calls it will be "2".

After 4 calls it will be 4.

Just paste this to firebug console:

function foo(x) {
  var tmp = 3;
  return function (y) {
    //console.log(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    console.log(x.memb);
  }
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);
bar(10);
bar(10);
bar(10);

console.log('result: ', age.memb)    // result: 4
Dziad Borowy
  • 12,368
  • 4
  • 41
  • 53