4

I am new to JS and was learning value and reference types in JS but I faced some confusion on the below code:

const obj = {
  arr: [{
    x: 17
  }]
};

let z = obj.arr;

z = [{
  x: 25
}];

console.log(obj.arr[0].x);

The above code outputs 17 but why? Well, arr is a reference type, that is, it is mutable then we equalize obj.arr to variable z so z holds reference to arr array in obj object. Finally, z holding 17 then we change it to 25 but it output 17.

FZs
  • 14,438
  • 11
  • 35
  • 45
Dickens
  • 775
  • 3
  • 8
  • 19

4 Answers4

3

First time, you have something like this:

obj ---> {
           arr ---+
         }        |
                  |
                  v
                  [
                     [0] ---+
                  ]         |
                  ^         |
                  |         v
                  |         { x: 17 }
                  |
                  |
z ----------------+

Note that z now points the same object as obj.arr but not obj.arr.

Modifying the value of z now will result in the value (and the reference) of z is changed, but obj.arr refers to the same object as before:

obj ---> {
           arr ---+
         }        |
                  |
                  v
                  [
                     [0] ---+
                  ]         |
                            |
                            v
                            { x: 17 }


z ----> [
          [0] ----> { x: 25 }
        ]

That's why obj.arr didn't change.

But how to change it via z?

You can't change obj.arr itself, but you can still mutate it.

Instead of your code, use this:

z[0] = { x:25 }

Now you have:

obj ---> {
           arr ---+
         }        |
                  |
                  v
                  [
                     [0] ---> { x: 25 }
                  ]         
                  ^         
                  |        
                  |         { x: 17 } -----> Garbage collection
                  |
                  |
z ----------------+

const obj = {
    arr: [{ x: 17 }]
};

let z = obj.arr;

z[0] = { x: 25 };

console.log(obj.arr[0].x);
FZs
  • 14,438
  • 11
  • 35
  • 45
1
const obj = {
 arr: [{ x: 17 }]
};

/**
 * z -> it is only reference to original object (const obj in our case). 
 * It is like another door to the same room
 */
let z = obj.arr;

/*
 * now z -> points to other value (array), but previous still exist
 */
z = [{ x: 25 }]; 

console.log(obj.arr[0].x);
0

You've just created z, which is a copy of obj.arr . If you change the value of z, the copy, the original (obj.arr) do not change.

I'm French that's why my english isn't perfect

  • 2
    I wouldn't say that `z` is a copy of `obj.arr`. "`z` refers to the same array as `obj.arr`" (the one with 17 in it) might be a better way to say it. After doing `z = [{ x: 25 }]`, `z` refers to a new array (the one with 25 in it). And `obj.arr` still refers to the first array (the one with 17 in it). – Wyck Sep 25 '19 at 17:07
0

The reference to obj.arr is replaced. z = [{ x: 25 }]; simply creates a new array with a new object, { x: 25 }, inside it. Then, it places a reference to this new array into z.

BCDeWitt
  • 4,372
  • 2
  • 19
  • 33