Jeff
Jeff

Reputation: 556

Javascript confusion over variables defined by reference vs value

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

Answers (3)

Jesse Good
Jesse Good

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

Mohammad Shraim
Mohammad Shraim

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

Josh
Josh

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

Related Questions