I don't understand spread operator

Tell us what’s happening:
Hi, I don’t understand what’s doing the spread operator (…) in this code that it is different from simply writing arr instead of …arr

Your code so far


//what's the difference between this:
const arr = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2 = [...arr];
console.log(arr2); // returns [ 'JAN', 'FEB', 'MAR', 'APR', 'MAY' ]

//and and this?:
const arr = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2 = arr;
console.log(arr2); // returns [ 'JAN', 'FEB', 'MAR', 'APR', 'MAY' ]



Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36.

Challenge: Use the Spread Operator to Evaluate Arrays In-Place

Link to the challenge:

The spread operator basically takes the individual values from one collection of things (and array, a string, a map or a set) and gives you them one-by-one. So [...arr] is saying “put the values in arr one by one into a new array”.

So the first one is a copy of arr, the second one is just arr

2 Likes

You can think of square brackets as “operator” to put something into array:

const arr = [1, 2, 3]; // put 1, 2, 3 into array

Spread operator is then the opposite - take things out of array:

...arr // => 1, 2, 3

So [...arr] means “take contents of arr out and put it into new array”

1 Like

Hello @Resurrexit,

The two codes does two very BIG different thing, even if it doesn’t seems like it.
Using spread operator here will let you create a copy of the first array; not assigning the first one to it.

Even if this seems like a minor deal, remember that in JS objects are passed by reference so:

const arr = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2 = arr;

arr2[0] = "BOB"

This will change the content of arr as well, since they point to the same memory locations.

While this:

const arr = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2 = [...arr];

arr2[0] = "BOB"

won’t since arr2 is pointing to a new, different, array.

hope this helps :slight_smile:

2 Likes

here is the difference

<script>
var arr = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
(function(a,b,c,d,e){
console.log(a,b,c,d,e);}
(arr));  //passed by reference

(function(a,b,c,d,e){
console.log(a,b,c,d,e);}
(...arr));// passed by value
</script>

Thanks this help! can you explain a little more when you say that “in JS objects are passed by reference”?

If arr = [1,2,3,4,5], then arr is pointing at the actual array itself, not the values in the array. The array is represented in memory as some code that in turn references where in memory the values it contains are stored. But arr is just the array itself.

If you do arr2 = arr, then arr2 is still the same reference to the same array in memory

Conceptually, it’s like a bag of values. When you say arr = [1,2,3,4], then the variable arr represents the bag, not what’s in the bag. Once you have that bag, you can check what’s inside, but the variable still just represents the bag itself.


As a comparison, note that you don’t have to remember this:

Very soon JavaScript will get two more data structures: tuples and records. A tuple looks like this:

tuple = #[1,2,3,4]

Now it looks the same as an array, except it has that # at the start. And it is very similar, in fact it’s almost exactly the same, you can do the same things with it. Except that tuple represents the value #[1,2,3,4]. So instead of tuple representing the container, it’s the container with those values inside.

Upside and downside of reference types (arrays, objects) is that it’s really easy to add and remove things. Upside and downside of tuples and records (the exact equivalents or arrays and objects) is that you can’t just add or remove things

1 Like

The best and most deep explanation you can get is probably found in this MDN page:

Without going too deep on the technicality my mental model when assigning JS objects is that they are “just” address.

An example:

var a = {fruit: "apple"}

If I were able to “inspect” what was actually inside a, I would not see the actual object, but rather an “address” (like the real life address) to where to find it in the memory of my pc.

This means that

var a = {fruit: "apple"}
//and
var b = {fruit: "apple"}

a === b // false

operations involving objects are different, like the above one, since I am not actually comparing the values, but rather the address where they are stored. And a and b above points into two different, unrelated, places.

Or in reverse:

var a = {fruit: "apple"}
var b = a;
var c = b;
var d = c;

Means that all the variable are pointing to the same address, so if the actual object is changed all of them will reflect it, since all they do is pointing to the right direction in the memory:

d.fruit = "banana"
console.log(a) // {fruit: "banana"}

Hope this won’t complicate things too much for you :slight_smile:

1 Like