Introduced in ES6, the spread operator gave more utility to users in a simple format. When we’re talking about composite data types, the spread operator allows us to make copies of the original data (whether it be an array or object) and create a new copy of it in memory. Composite data types when instantiated in javascript point to the data in memory, what this means is the data is created in memory and the variables are references to the data in memory. This gets dodgy because if you initialize the data to a new variable you are making another copy of the reference, meaning it points to the same data in memory so if you make any changes to either of the newly initialized variables it will make changes to all copies.
What the spread operator does is it creates a new array or object in memory, it takes the each individual element in the array or object and makes an exact copy of it in memory. The syntax looks like so:
lets say you created an array a:
let a = [1,2,3]
you want to make an exact copy (a deep copy) initialized to a new variable b:
let b =[…a]
and…thats it! Using the spread operator has huge benefits in making a code base more readable and organized, but it does come with pitfalls if the user is unaware of them.
The spread operator makes deep copies of data if the data is not nested. When you have nested data in an array or object the spread operator will create a deep copy of the top most data and a shallow copy of the nested data. lets take a look at what this means.
lets say I have an array c that looks like this:
let c = [1,2,[3,[4,5]]]
If we spread this data to a new variable (d):
let d = […c]
It looks like we get a deep copy but in fact we don’t! When we index into our new array(d) we get the following:
console.log(d[0])
1
console.log(d[1])
2
console.log(d[2])
[3,[4,5]]
console.log(d[2][1])
[4,5]
It looks right! But its not! The major pitfall happens when we try to change the existing data. If we change the data for variable d at index 0 and 1 it works as expected! These values were created in memory as a new array. However when we change the array saved at index 2(d[2][1]) not only does it change the data for our variable d but c as well. This goes back to how javascript saves data so instead of a variable that we instantiated the reference is now the index of the array, so this means d[2][1] points to the same array that c[2][1] points to in memory. CONFUSING, ANNOYING but now you know. So what do you do? You spread that value as well. So when written correctly this looks like:
let d = […c]
d[2] = […c[2]]
this changes the reference at d[2] to a new array created with the spread operator! If you wanted to use the spread operator to copy an object you would have to apply the same methods!