misterwolf
misterwolf

Reputation: 424

Passing an hash through parameter

I'm a little confused about the passing of a hash as parameter to a function. I know that when a variable is passed to the function through a parameter, to this is applied a copy of the value. But this is not valid with the hashes, at least not always. Example:

var a = {b: 'hello world'};
var change = function(h){
    h = true;
};
var change_v2 = function(h){
  h.b = 'another hello';
};

console.log(a); // will print the original hash
change(a); 
console.log(a); // naturally, will print the original hash
change_v2(a); 
console.log(a); // this print b == 'another hello'

So, why the reference is used sometime for the hashes? Can someone explain how javascript works in this case?

Upvotes: 2

Views: 1366

Answers (3)

cdhowie
cdhowie

Reputation: 169133

The simple answer to your question is that a value was copied -- a does not contain any object (what you called a hash) but actually contains a reference to the object and this reference was copied into the parameter local.

Read below for a more detailed explanation of why this happens, pass-by-value vs pass-by-reference.


In JavaScript, variables do not hold objects, they hold a reference to an object. This is an important distinction.

All parameters are pass-by-value in JavaScript. The object references stored in variables are passed by value.

These two behaviors combine to cause the specific behavior you are seeing. Let's lay out some examples of each passing behavior to prove that JavaScript passes arguments by value.


function foo(a) {
    a.bar = 2;
}

var b = { bar: 1 };
foo(b);

b.bar would still be 1 if objects were passed by value, but this is not the case in JavaScript.

b.bar would be 2 if (a) the object reference was passed by value, or (b) the argument itself was passed by value.

So in this case, "pass reference by value" and "pass argument by reference" don't have a difference in behavior. Now let's introduce a case where they are different.

function foo(a) {
    a = { bar: 2 };
}

var b = { bar: 1 };
foo(b);

b.bar will be 1 if the object is passed by value, which isn't what happens.

b.bar will also be 1 if the object reference is passed by value, which is what happens.

b.bar will be 2 if the argument is passed by reference.


So in summary, you have to realize two things:

  1. Variables never contain objects, but they can contain a reference to an object. Two variables both holding a reference to the same object will reflect changes made to that object.

  2. All arguments are passed by value, that is, the callee has no access directly to the variable that was passed in, but only to the value received by the parameter -- which can be an object reference. Manipulation of that object can cause the appearance of pass-by-reference, but note that the variable passed into the function still refers to the same object so the passed variable was not modified in any way.


As a side note, if objects were values that could be directly stored in variables, then {} === {} would be true, but it's not -- because the references are compared and found to be not equal, as these references refer to two different objects.

Upvotes: 3

sid-m
sid-m

Reputation: 1554

This is because JavaScript passes parameters by value. Passing a parameter by value is like assigning formal parameters values to actual parameters. For example consider

function f(obj) { obj.a = 10; }
o = { a : 20 };
f(o);

The above code will function as if the value of o is assigned to obj like if you do

o = { a : 20 }
obj = o;
obj.a = 10;
console.log(o.a);

you will see the same effect.

See a detailed explanation here

Upvotes: -1

dsh
dsh

Reputation: 12214

Javascript is pass-by-reference. Always. Assignment changes a name to refer to some value.

So,

function foo(h)
   { h = "bar"; }

The name h is a parameter to the function. The assignment affects the name h only, and that name exists only in the scope of the call to the function.

In contrast, the statement h.b = "bar"; does not assign to the name h. It assigns to the field b within the object that is referenced by the name h.

Upvotes: 0

Related Questions