Reputation: 232
As I understand objects are passed by reference in JavaScript (and primitives are passed by value?).
var a, b;
a = {
Foo: "Bar"
}
b = a;
a.Foo = "Other";
console.log(b.Foo); // "Other"
This worked similarly with arrays but did not work like I expect with functions:
var a, b;
a = function(){ return 20; }
b = a;
a = function(){ return 40; }
console.log(b()); // returns 20 ?
I'm confused because I thought functions are objects. Shouldn't the above example return 40?
Upvotes: 5
Views: 141
Reputation: 310947
Further to @thefoutheye's answer, consider the following proof of your statement functions are objects:
var a, b;
a = function() { return 20; }
a.Foo = "Bar";
b = a;
a.Foo = "Other";
console.log(b.Foo); // "Other"
Upvotes: 2
Reputation: 700362
First regarding the question in the title (which is actually different from what you demonstrate with the code examples):
"As I understand objects are passed by reference in JavaScript"
No, Javascript doesn't support passing parameter by reference at all. All parameters are passed by value, but the value can be a reference.
Example:
var a = { answer: 42 };
function f(x) {
alert(x.answer); // shows 42
x = { answer: 0 };
alert(x.answer); // shows 0
}
f(a);
alert(a.answer); // shows 42
As the parameter is passed by value, the variable x
is separate from the variable a
, so assigning a new object to x
doesn't change the value of a
.
Back to your code:
When you assign an object reference from a variable to another, it's the reference that is copied, not the object. You get two variables that reference the same object.
Either of the variables can be used to access members in the object, which your first code example demonstrates.
If you assign a new object to the first variable, you will replace the reference in the variable, you will not overwrite the object that it currently points to. The object is still intact, and the second variable still points to it. You get two variables that point to one object each, which your second code example demonstrates.
Upvotes: 2
Reputation: 324650
You are reassigning the variable a
to a new function. That's not the same as changing a property value.
Try:
var a, b;
a = {Foo: function() {return 20;}};
b = a;
a.Foo = function() {return 40;};
console.log(b()); // returns 40
Upvotes: 1
Reputation: 239483
In the first case, a.Foo = ...
, You are changing the value of a property in the object, referred by both a
and b
. This is called mutating an object.
But in the second case, you are making a
refer a new function object. Now, a
and b
are referring to different function objects.
That is why you are getting 20
in the second case.
Upvotes: 11