Reputation: 424
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
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:
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.
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
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
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