Search code examples
javascriptvariablesmutability

Array mutability and variable reference scenario is unclear


So, I understand that arrays in JavaScript are mutable.

Meaning that if I create array a, and array b = a, then if I modify array a, the modification is also visible in array b.

However, in the following scenario I don't understand why b loses the "reference" to array a.

var a = [1,2,3];
var b = a;

console.log('a =', a);
console.log('b =', b);

a[0] = 4;
console.log('a =', a);
console.log('b =', b);

a = [5,5];
console.log('a =', a);
console.log('b =', b);


Solution

  • Let's look into the computers memory¹. First of all, two variables get created, a and b. These are basically memory locations, that get filled with a value:

     location | name²      |  value
     -------------------------------------
      1       |  a         |  undefined
      2       |  b         |  undefined
    

    Now a gets initialized, and a new array gets created. That array however doesn't get stored under the variable directly, but at another location, inside a there is just a reference to that location:

      location | name²      |  value
      -------------------------------------
      1        |  a         |  ➡️ 3
      2        |  b         |  undefined
      3        |            |  [1, 2, 3]
    

    Now when you do b = a the reference gets copied, you end up at:

      location | name²      |  value
      -------------------------------------
      1        |  a         |  ➡️ 3
      2        |  b         |  ➡️ 3
      3        |            |  [1, 2, 3]
    

    Now when you do a = [5,5] another array gets created, and a references that. b wasn't changed though, it still references the other array.

      location | name²      |  value
      -------------------------------------
      1        |  a         |  ➡️ 4
      2        |  b         |  ➡️ 3
      3        |            |  [1, 2, 3]
      4        |            |  [5, 5]
    

    Or if you do b = {value: a} :

      location | name²      |  value
      -------------------------------------
      1        |  a         |  ➡️ 4
      2        |  b         |  ➡️ 5
      3        |            |  [1, 2, 3] // waiting for GC
      4        |            |  [5, 5]
      5        |            | { value: ➡️4 }
    

    ¹ yes, JavaScript is an interpreted language, so you won't know for sure how it ends up in the memory in the end, thats up to the engine. However, JS derives its concepts from other languages, and thats why it is often helpful to think on a low level.

    ² there is no such thing as a name of a specific memory location, I just added that for clarity.