Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - Empty an Array / Object while Passing by Reference Issue

to my understanding, both array and objects are Pass By Reference based on the memory address, so if I create another variable and point to the array/object, and mutate any of the values, another value should also be changed.

However, I don't quite understand how it works here. I am pointing to array1 and modifying array1 to empty, why the value at anotherArray does not change?

   var array1 = [1,2,3,4,5,6,7];  // Created array
   var anotherArray = array1;     // Referenced array1 by another variable
   array1 = [];                   // Empty the array
   console.log(anotherArray);  // Output [1,2,3,4,5,6,7]

I can understand the below example why the anotherArray becomes [] empty because it is passed by reference, but why the anotherArray still output [1,2,3,4,5,6,7] for the above?

   var array1 = [1,2,3,4,5,6,7]; // Created array
   var anotherArray = array1; // Referenced array1 by another variable
   array1.length = 0; // Empty the array by setting length to 0
   console.log(anotherArray); // Output []

Thank you.

like image 571
cHappiness Avatar asked Dec 18 '21 20:12

cHappiness


3 Answers

Assigning to a variable never changes the object that the variable previously had as value.

Objects -- such as arrays -- only change when you mutate them, either through calling a method that does this, or by setting a property.

Here is a visualisation of your first script:

var array1 = [1,2,3,4,5,6,7] results in this:

  array1
   ↓
  ┌──────┬───┬───┬───┬───┬───┬───┬───┐
  │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
  ├──────┼───┼───┼───┼───┼───┼───┼───┤
  │  7   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
  └──────┴───┴───┴───┴───┴───┴───┴───┘

After var anotherArray = array1 we have this:

  array1
   ↓
  ┌──────┬───┬───┬───┬───┬───┬───┬───┐
  │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
  ├──────┼───┼───┼───┼───┼───┼───┼───┤
  │  7   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
  └──────┴───┴───┴───┴───┴───┴───┴───┘
   ↑
  anotherArray

Then array1 = [] will create a new array: so there are now two arrays. It also makes array1 a reference for the newly created array:

  array1
   ↓
  ┌──────┐
  │length│
  ├──────┤
  │  0   │
  └──────┘

  ┌──────┬───┬───┬───┬───┬───┬───┬───┐
  │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
  ├──────┼───┼───┼───┼───┼───┼───┼───┤
  │  7   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
  └──────┴───┴───┴───┴───┴───┴───┴───┘
   ↑
  anotherArray

In the second script the assignment to the length property (actually a setter) will mutate the array. There is no new array created, and the values 1,2,3,4,5,6,7 are lost:

  array1
   ↓
  ┌──────┐
  │length│
  ├──────┤
  │  0   │
  └──────┘
   ↑
  anotherArray
like image 196
trincot Avatar answered Oct 07 '22 18:10

trincot


For your first example, you are actually making a reassignment to array1 as an empty array (and now they are pointing to 2 different arrays in the memory), hence the anotherArray remains unchanged.

 var array1 = [1,2,3,4,5,6,7];  // Created array
 var anotherArray = array1;     // Referenced array1 by another variable
 array1 = [];                   // Empty the array
 console.log(anotherArray);  // Output [1,2,3,4,5,6,7]

In this case, you are actually modifying the array by assigning it's length to 0. since array1 refers to it, it impacts on him as well since they are referring the same array in the memory.

  var array1 = [1,2,3,4,5,6,7]; // Created array
  var anotherArray = array1; // Referenced array1 by another variable
  array1.length = 0; // Empty the array by setting length to 0
  console.log(anotherArray); // Output []
like image 1
Ran Turner Avatar answered Oct 07 '22 16:10

Ran Turner


The line

array1 = [];

does not modify the array object previously assigned to array1. It assigns a new (empty) array to the variable; it's not like invoking an operation on the object assigned to array1.

To explain it in other words, assume array1 was the only variable referring the previously assigned array object ([1,2,3,4,5,6,7]). Upon execution of that line (which is a statement, btw) you got lost of the previously assigned array; and it would be garbage collected some time later. This is all because the assignment operator is used here and they way its operational semantics is defined in JavaScript.

What is more, your are misusing the concept of pass by reference here (a.k.a. call by reference); which is a concept that relates to how values are passed to arguments of functions calls (or sub routines/procedures, if you prefer speaking of sub routines/procedures rather than functions).

like image 1
twwwt Avatar answered Oct 07 '22 17:10

twwwt