Javascript passes objects by reference. This makes perfect sense. But once you start manipulating those objects, everything acts in a way that seem unintuitive. Let me offer an example:
var a, b;
a = {}
b = a;
a['one'] = {};
console.log( JSON.stringify(a) );
// outputs: {"one":{}}
console.log( JSON.stringify(b) );
// outputs: {"one":{}}
This is all well and good because now b
has a pointer to a
so it's expected that assigning stuff to a
will also affect b
.
But then if I do this:
a = a['one'];
console.log( JSON.stringify(a) );
// outputs: {}
console.log( JSON.stringify(b) );
// outputs: {"one":{}}
This is surprising to me. I'd expect a
and b
to still be the same (and to be {}
since a['one']
was previously set to {}
and a
was set to a['one']
).
But that's not the case. It appears that a
loses its reference to b
when it's assigned to something new, but b
maintains the value that a
was set to prior to a
loosing its reference to b
.
But then if I do this:
a['two'] = 2;
console.log( JSON.stringify(a) );
// outputs: {"two":2}
console.log( JSON.stringify(b) );
// outputs: {"one":{"two":2}}
What? a
has clearly lost it's reference to b
, but b
seems to still have some reference to a
.
Does the empty object {}
point to some place in memory so every variable referencing it is now pointing to the same place?
Can someone with a firm grasp on this explain it to me?
Following your example line by line:
a = {}
a
now references the new object.
b = a;
b
now references the same object that a
references. Note that it does not reference a
.
a['one'] = {};
The new object now has an index 'one'
that references another new object.
When you do
a = a['one'];
You are setting a
to refer to a['one']
, which is that new object you created when you did a['one'] = {}
. b
still references the object you created with a = {}
.
You are confusing the issue when you say "a
has lost its reference to b
" because a
does not refer to b
, nor vice versa. a
and b
refer to objects, and they can be made to refer to other objects. Like this:
With a = {}; b = a
, you get
a
\
\
{ }
/
/
b
Then with a['one'] = {}
you get
a
\
\
{ one: { } }
/
/
b
Then with a = a['one']
you get
a - - - -
\
{ one: { } }
/
/
b