1

Not sure if this is the correct way to word my question. If I set up the following piece of JavaScript code:

var x = 5;
var y = function(z) {
    z=7;
    return z;
}
y(x);
x;

I get 7 returned from the function call but x stays its original value. I thought JavaScript variables call by reference so how come x's value isn't actually changed through the function?

user2066880
  • 4,825
  • 9
  • 38
  • 64

2 Answers2

3

The real problem here is that you're not mutating anything; you're just reassigning the variable z in the function. It wouldn't make a difference if you passed an object or array.

var x = ['test'];
var y = function(z) {
    z=['foo'];
    return z;
}
y(x);
x; // Still ['test']

Now, what others have said is also true. Primitives cannot be mutated. This is actually more interesting than it sounds, because the following code works:

> var x = 1;
> x.foo = 'bar';
"bar"
> x
1
> x.foo
undefined

Notice how the assignment to x.foo was seemingly successful, yet x.foo is nowhere to be found. That's because JavaScript readily coerces primitive types and object types (there are "object" versions of primitives, that are normal objects). In this case, the primitive 1 is being coerced into a new object (new Number(1)), whose foo attribute is getting set, and then it is promptly destroyed, so no lasting effects occur.

voithos
  • 68,482
  • 12
  • 101
  • 116
  • Oh ok. So when I reassign `z` in the function, `z` and `x` don't point to the same array/object? I thought that's what calling by reference meant. Could you help me understand what I'm not getting? Thanks again for the answer! – user2066880 Jul 15 '13 at 16:49
  • 2
    @user2066880 - They are the same object until you reassign `z` inside the function. Up to then, you could use `z` to modify the object, and those modifications would be seen in the calling code. If you replaced `z=['foo'];` in this code with `z[0] = 'foo';`, then `x` in the calling code would be changed to `['foo']`. – Ted Hopp Jul 15 '13 at 16:50
2

Thanks to @TeddHopp about this note:

Only the value is passed for all variables, not just primitives. You cannot change a variable in the calling code by passing it to a function. (Granted, you can change the object or array that may be passed; however, the variable itself remains unchanged in the calling code.)

If you want the value of x to change anyways you can do:

x = y(x);
Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
  • Only the value is passed for all variables, not just primitives. You cannot change a variable in the calling code by passing it to a function. (Granted, you can change the object or array that may be passed; however, the variable itself remains unchanged in the calling code.) – Ted Hopp Jul 15 '13 at 16:49
  • Thanks. you learn something new everyday. guess I'm more used to Java :) – Yotam Omer Jul 15 '13 at 16:52