buley
buley

Reputation: 29248

Are there any rules of thumb for when JavaScript values are copied by reference and not by value?

Even as a somewhat seasoned JS dev I find myself constantly suprised at shallow vs. deep copies of objects.

Are there any rules of thumb for when JavaScript values are copied by reference and not by value for the major object types? For example, I know string values are always copied by value not reference.

Upvotes: 6

Views: 546

Answers (2)

josh3736
josh3736

Reputation: 145002

In JavaScript, all objects are stored and passed 'by reference'.

var a = { v: 'a' }, b = { v: 'b' };
a=b;
b.v='c';

a and b will reference the same object; a.v == 'c' and b.v == 'c'.

Primitive datatypes (string, number, boolean, null, and undefined) are immutable; they are passed by value.

var a = 'a', b = 'b';
a=b;
b='c';

Since we're dealing with primitives, a == 'b' and b == 'c'.


Pedants will tell you that JavaScript isn't pass-by-reference in a classical sense, or that it's a "pure pass-by-value" language, but I think that complicates things for practical purposes. No, you can't directly modify an argument passed to a function as if it were a variable (which would be true if the language were true pass-by-reference), but you also don't receive a copy of an object passed as an argument (as you would if it were true pass-by-value). For most purposes (from the standpoint of the language's user, you), objects passed to a function are references, since you can modify that object and it affects the caller's object. See also the fantastic answers to this question.

Upvotes: 4

Šime Vidas
Šime Vidas

Reputation: 185973

OK, let me explain your code:

var x, y;
x = { 'blah': 'foo' };
y = x;
x = { 'bar': 'bas' };

So, you declare two variables, and then you assign an object value to the first variable:

x = { 'blah': 'foo' };

So, what happens here:

  1. The object literal - { ... } - is evaluated, which results in the creation and initialization of a new native object.
  2. A reference to this object is assigned to the variable x.

Next, this line

y = x;

merely copies the reference which is stored in x to the variable y. Now both variables store the same reference to the object.

Finally, this line

x = { 'bar': 'bas' };

assigns a new value to the variable x. The object literal is evaluated which results in the creation/initialization of another object, and a reference to that object is stored in x.

The variable y, however, still holds a reference to the first object.

Upvotes: 2

Related Questions