Reputation: 556
I understand the following property of the javascript language:
var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1
However, when trying to apply this logic to an object it seems to act differently:
var bar = {};
bar.prop = 1;
var foo = bar;
bar.prop = "something entirely different";
// foo.prop now changes to "something entirely different"
// but...
bar = "no longer an object";
// now foo remains an object with the prop property
Can someone tell me what's happening and why there is a difference?
Upvotes: 5
Views: 677
Reputation: 52405
Let's take it line by line:
var foo = bar;
All that names of objects do is hold addresses in memory. So in this statement, you are making foo
hold the same memory address as bar
. If for example bar
was holding 0xFF, then via the assignment you would make foo
also hold 0xFF.
However, keep in mind that bar
and foo
are two distinct objects, they happen to just hold the same address in memory.
Now, since they do happen to hold the same address in memory, mutating members of bar
will also affect the members of foo
because they are bound to the same object.
bar.prop = "something entirely different"; // affects foo.prop also
However, here is the key point to remember:
Assignment only changes what the name of the object is bound to, and does not affect any other objects.
In other words, the statement below made bar
hold a different memory address, but this does not affect foo
.
bar = "no longer an object"; // Made bar hold a different memory address
Now, explaining the quote:
Javascript is always pass by value, but when a variable refers to an object (including arrays), the "value" is a reference to the object.
Take this example:
function f(obj1, obj2)
{
obj1.prop = 10;
obj2 = {prop: 20};
}
var bar = {prop: 1};
var foo = {prop: 2};
f(bar, foo);
console.log("bar.prop: " + bar.prop + ", foo.prop: " + foo.prop);
This prints outs: bar.prop: 10, foo.prop: 2
. Inside function f
, obj1 holds the same memory address as bar
and obj2 holds the same memory address as foo
. However, only bar is affected because inside f
only altering members of objects are reflected and assignment obj2 = {prop: 20};
only affects the local variable obj2
not foo
.
In other words, the "value" is a reference to an object
means, altering members affects the referenced object but assigning only affects the local variable.
Upvotes: 1
Reputation: 1323
In the first code you define the Var bar as variable.
in the second code you define it as an object.
The variables take a place in the memory;so when you define foo from bar its will be the same type as variable and will reserve a new memory location; and when you use equal operator you are replacing the data content of this variable.
The object in the second sample code on initialize will point (as pointer) to a memory location that will contain the data of this object; and when you define foo from bar its will be the same type as object and will point to the same memory location; so changing one of these two reference object value will reflect on the other one.
Upvotes: 0
Reputation: 11070
That's correct. When you assign a variable to an object, you're really creating a second reference to that object. In the first case, what you're doing is assigning bar
to point at the string foo
points to, but then you change what bar
points to when you reassign bar
.
In the second example, you assign bar
to a new object, then you point foo
at that same object, then you reassign bar
to a string. foo
is still pointed at the same object.
Think of it like this: bar = "something"
is changing what bar
points to, not changing the actual object {}
to a string.
This article is a fairly good explanation of what you're seeing. I'm looking for even better / more authoritative references, however.
Upvotes: 1