Stereo99
Stereo99

Reputation: 232

Understanding pass by reference vs value with functions

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

Answers (4)

Drew Noakes
Drew Noakes

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

Guffa
Guffa

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

Niet the Dark Absol
Niet the Dark Absol

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

thefourtheye
thefourtheye

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

Related Questions