Arr2 = arr vs arr2 = ([...arr]) What is the difference?

Don’t understand why initial array is changed in this example

let itemList = ["item1", "item2", "item3", "item4"];
function add (obj, value) {
  let list = obj;
  console.log(obj); // item1,item2,item3,item4
  console.log(list) // item1,item2,item3,item4
  list.push(value);
  console.log(obj); // item1,item2,item3,item4,item99
  console.log(list) // item1,item2,item3,item4,item99
  return list;
}

let newItemList = add(itemList, 'item99');

Please check my post in this thread:

1 Like

When assigning arr2 = arr, then arr2 is arr. Any changes made to arr will also change arr2. In other words, it’s just giving arr another name.

On the other hand, arr2 = [...arr] will make arr2 a copy of arr. As a copy, this makes them distinct, so changes to one won’t show up in the other (it’s a shallow copy though, but we don’t need to care about that just yet).

I always say that I have an advantage in that I learned the C language first because things like this make perfect sense there.

The variable refers to a discreet memory location. In JavaScript, for primitive types (number, string, boolean, etc.) the variable actually holds the value itself. So, something like:

num1 = num2;

… works exactly as you would expect - it copies the value of num2 into the memory slot of num1 and now you have two copies of the variable.

But it is different with non-primitives. In JavaScript that means objects. (Remember that in JavaScript that all non-primitives are types of objects, things like arrays, functions, classes, etc.) These things are too big to fit in a memory location so instead of the variable holding the value itself, it holds the address of the place in memory where the object it. This is very important. So, if you do something like:

arr1 = arr2;

… you aren’t copying the array, but are copying the address of the array. So, you still have only one copy of the array, but two addresses that point to the same array. This is also why when you pass an array (or any object) into a function and make changes inside the function to that “copy” of the array, the original is changed. This is because you are not sending the array itself but the address of it, also called “by reference”.

So, if you truly want two copies of an array, you have to make a completely new array and assign that to the new variable.

The pre-ES6 way to do this was:

arr1 = arr2.slice();

… but now we have:

arr1 = [...arr2];

One of the cool things about JavaScript is that it takes care of a lot of this behind the scenes stuff. But unfortunately that means that a lot of people never truly understand what is going on under the hood. In some languages (like assembly or C) you must understand these things because you have to manually manipulate them. But JavaScript takes care of it for you.

1 Like

There is also a good explanation here.