thetrystero
thetrystero

Reputation: 6112

Function arguments passed by value

I'm reading that in JavaScript, a common point of confusion arises because variables of primitives are passed by value, and variables of objects are passed by reference, while in function arguments, both primitives and references are passed by value.

In the course of my tinkering, I've made up the following code, but am having trouble wrapping my head around it.

> function setName2(obj) {
... obj.name="matt";
... obj = new Object();
... obj.name="obama";
... }

If I set

var person = new Object();
person.name = "michelle";

Then run

> setName2(person);

I get

> person.name;
'matt'

Which makes sense because the new object created is a pointer to a local object, hence not affecting the property of the global 'person'.

However, what if I first set

 var obj = new Object();
    obj.name = "michelle";

Then run

  > setName2(obj);

?

I get the same outcome. Does this mean that the compiler recognizes the two variables of the same name (obj global and obj local) as references to different locations within the heap, each having some different pointer association, or is there a different explanation for this phenomenon?

Upvotes: 1

Views: 192

Answers (5)

garst
garst

Reputation: 6062

Javascript uses pass-by-value.

The confusion is that objects are hold by reference variables (kind of pointers). In fact most common languages (java, javascript, etc.) do not have a real pass-by-reference behaviour. Another way to understand this could be pass-reference-by-value, although, formally, there is not such a thing.

That means when you pass an object as a parameter, you are actually passing a reference to the object by-value.

function setName2(obj) {
  ...
}

setName2(person);

here the contents of person (a reference, or "pointer" if you like) is copied by-value to a new local variable: obj.

obj and person are different variables that hold a reference to the same object.

So, doing obj = new Object(); makes obj to point to the new object. But person is unaffected since it is still a completely different variable.

Upvotes: 1

Wiktor Zychla
Wiktor Zychla

Reputation: 48314

The confusion comes from the fact that "passed by reference" is misinterpreted by people or used in a wrong sense.

Parameters are passed by value. This means that changing the value inside the method doesn't change the original value.

In case of primitives, the value of a primitive is its value. In case of objects, the value of an object is a reference to it. You can access and change object's content but you can't change the value of the reference itself.

In other programming languages, like C++ or C#, "passing by reference" means that you pass: - a reference to a primitive type - a reference to a reference to an object In such case, not only the content of an object can be changed but also a reference itself can be changed.

There is NO passing by reference in Javascript.

Upvotes: 1

Jon
Jon

Reputation: 437804

JavaScript does not have pass-by-reference; everything is passed by value. However, some values are themselves references to objects. This distinction (pass-by-reference vs. is-a-reference) leads to much confusion.

An example to clear things up:

function f(o) { ... }
var obj = { foo: 42 };
f(obj);

No matter what you do in f, obj will always refer to the same object because the argument is not passed by reference. However the value obj, which is copied into o, is itself a reference to an object. This is why any property changes made to o inside the function will be visible on obj after it returns.

Upvotes: 2

Quentin
Quentin

Reputation: 944434

while in function arguments, both primitives and references are passed by value.

This is not true. There is nothing special about function arguments.

function setName2(obj) {

This accepts a reference to an object as an argument.

obj.name="matt";

This modifies the name property of the object that reference points to.

obj = new Object();

This replaces the reference to the original object with a reference to a new object.

obj.name="obama";

This modifies the name property of the new object. The original object is unchanged.

Upvotes: 1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324790

I don't know where you read that, but it's absolutely not true. Objects are passed by reference, full stop. Whether or not it's a function parameter is completely irrelevant.

Upvotes: 0

Related Questions