Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion over references to functions with properties in Javascript

In the following javascript code:

function foo() {
  foo.val =  foo.val || 'no val';
  return 'foo has ' + foo.val;
};
function bar() {
  bar.val =  bar.val || 'no val';
  return 'bar has ' + bar.val;
};
var a = foo;
foo.val = '1';
bar.val = '2';
a.val = '3';
foo = bar;
'foo says "' + foo() + '", bar says "' + bar() + '", a says "' + a() +'"';

what I would expect would be:

foo says "bar has 2", bar says "bar has 2", a says "foo has 3"

However, when run from the Firebug console in Firefox 10.0.2 I get:

foo says "bar has 2", bar says "bar has 2", a says "foo has 2"

Can anyone explain to me the sequence of events that goes on behind the scenes to make this so? Why does a stay bound to the original foo function (as I would expect) but hold bar's value for val?

like image 417
beldaz Avatar asked Feb 22 '23 06:02

beldaz


2 Answers

After this line of code:

var a = foo;

a points to the same function that foo points to. In

foo = bar;

you reassign foo to point to whatever bar refers to. This doesn't update a's reference — it still points to the function that foo also originally pointed to.

Now, when you run a(), the original function is executed. It grabs foo (which now points to bar's reference) and gets its val property. The val of bar's object is 2, so this is what is returned.

It's a bit difficult to explain in words.. would a diagram be easier to understand, perhaps?

like image 183
Jon Gauthier Avatar answered Apr 08 '23 09:04

Jon Gauthier


When the foo() function executes via the a() call, its code says to get the value of foo.val, that is, the val property of whatever foo refers to at that moment. So your a() function effectively looks like this:

function a() {
  foo.val =  foo.val || 'no val';
  return 'foo has ' + foo.val;
};

But foo at that point is just a reference to bar.

like image 37
nnnnnn Avatar answered Apr 08 '23 09:04

nnnnnn