I am puzzled by the behavior of mutability and immutability when assigning values to variables in JavaScript. I have observed four cases with varying results, some mutating the value while others do not. Can anyone provide a clear explanation on how this concept really works? It seems like a common interview question, but I struggle to articulate it...
Case 1
const x = { a: 1, b: 2 };
function fn1(_x) {
_x.a = 0;
}
fn1(x);
console.log(x);
// { a: 0, b: 2 } mutated
Case 2
const y = { a: 1, b: 2 };
function fn2(_y) {
_y = 0;
}
fn2(y.a);
console.log(y);
// { a: 1, b: 2 } not mutated
From these code samples, it appears that the value of an object's property cannot be changed if not explicitly assigned within the function.
Case 3
const z1 = { a: 1, b: 2 };
function fn3({ a }) {
a = 0;
a.c = 0;
}
fn3(z1);
console.log(z1);
// { a: 1, b: 2 } not mutated
Case 4
const z2 = { a: {}, b: 2 };
function fn3({ a }) {
a = 0;
a.c = 0;
}
fn3(z2);
console.log(z2);
// { a: {}, b: 2 } not mutated
In Case 4, I expected { a: {}, b: 2 }
. Why is the value of z2
mutated but z1
remains unchanged? Could it be because String
and Number
are immutable?
Based on these experiments, can I conclude that a value will only change if explicitly assigned to a property of an object within a function? I also assume that the behavior of arrays follows the same rules as objects.
Thank you!
UPDATE:
Case 5
const z2 = { a: {}, b: 2 };
function fn4({ a }) {
a.c = 0;
a = 0;
}
fn3(z2);
console.log(z2);
// { a: { c: 0 }, b: 2 } mutated
Patrick Roberts pointed out that the previous Case 4 was actually not mutable, which I had overlooked... However, what caught my interest was that by changing the order of a.c = 0;
and a = 0;
in Case 5 (now fn4
), the output changes... but at this point I'm stuck. Apologies for the error in Case 4.