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.
JavaScript is always pass-by-value. This means everything in JavaScript is a value type and function arguments are always passed by value.
Therefore, even changing the argument inside the function doesn't affect the variable passed from outside the function. It is important to note that in javascript, all function arguments are always passed by value. That is, JavaScript copies the values of the passing variables into arguments inside of the function.
Javascript is always pass by value, but when a variable refers to an object (including arrays), the "value" is a reference to the object. Changing the value of a variable never changes the underlying primitive or object, it just points the variable to a new primitive or object.
It's always pass by value, but for objects the value of the variable is a reference. Because of this, when you pass an object and change its members, those changes persist outside of the function. This makes it look like pass by reference.
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.
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:
{ ... }
- is evaluated, which results in the creation and initialization of a new native object.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With