TO SPREAD OR NOT TO SPREAD, THAT IS THE QUESTION!

By: Saurav

2019-03-30 08:31:00 UTC

I have been confused with the spread operator. The three dots you see especially if you work in the reactJS domain. Finally, I feel I understood it and wanted to share with you. As per the definition:

Spread syntax allows an iterable such as an array 
expression or string to be expanded in places where 
zero or more arguments (for function calls) or elements (
for array literals) are expected, or an object expression 
to be expanded in places where zero or more key-value 
pairs (for object literals) are expected.

If you got the meaning in the first go, good for you. I have respect for you.

Let's try explaining in plain English for the others (including myself) :

The spread operator takes individual items from anything you 
can iterate over (like an array, strings, hash, sets, etc), and 
makes them available (aka spreads it) in the place you are 
invoking it (aka the receiver).

What it means is if you have a string "SAURAV" (which is iterable), and you use spread operator to spread it inside another array or hash, each individual characters will be spread in that array/hash as shown below:

var a = "SAURAV"
var b = [...a]
var c = {...a}

b 
// returns ["S", "A", "U", "R", "A", "V"]

c
// returns {0: "S", 1: "A", 2: "U", 3: "R", 4: "A", 5: "V"}

Interesting right? Now, suppose you want to print an array from console.log as a string, how would you go about it?

One old way would be to use join like the one shown below. However, a better alternative is to just use spread on the contents of the array. Keep in mind, the contents of the array are not an array, they are strings. If you provide multiple strings to a console.log(), it will print a one large string joining all of them. Voila!

console.log(['My', 'name', 'is', 'bond', 'james', 'bond']) //returns an array of strings
console.log('My', 'name', 'is', 'bond', 'james', 'bond') // returns My name is bond james bond

const items = ['My', 'name', 'is', 'bond', 'james', 'bond']; 
['My', 'name', 'is', 'bond', 'james', 'bond'].join(' ') // returns My name is bond james bond as well 

// Let's say we have this array of strings. When we use 
spread operator on this array (take the string items out) 
and make it available to console.log(...items), it would 
actually pass each individual items as string arguments 
to the console.log() function. Therefore, the result will be:

My name is bond james bond

Similarly, for Math.min() function, we provide numbers separated by commas. If we have an array of numbers and we want to just pass in all the individual numbers, we can use our spread operator again:

Math.min(1,2,3) // would give us 1

Math.min(...[1,2,3]) //would give us 1 as well

//Same logic

For a hash, it becomes interesting.

It does copy the contents of first hash to another but it does a shallow copy for nested levels. What it means it for the first level, new values are created but for next levels of nesting it copies items by reference, not value:

var obj1 = { name: {first: 'Foo', last: 'Bar'}, age: 22 } // Lets say we have the first object obj1

var newObj = {...obj1} // We use spread operator to spread the contents of the first hash. So far so good. 

// newObj returns  { name: {first: 'Foo', last: 'Bar'}, age: 22 }

//Now, we change the age and first name of newObj

newObj.age = 25
newObj.name.first = "Saurav"

//newObj returns  { name: {first: 'Saurav', last: 'Bar'}, age: 25 }



//Let's see what the old obj1 returns:

obj1 // returns  { name: {first: 'Saurav', last: 'Bar'}, age: 22 }  ! oops





As we see above, although the first level of nesting, which was age was copied by value and there was no reference to the age of obj1, the second level which was first and last name were changed as they were copied by reference.

Bottomline: If you plan on using spread on a nested hash, apply spread on each nested hierarchy.

Note: Don't confuse Spread with Rest (Although you will and it's fine)

One last important syntax which looks exactly like the spread is the rest operator used for destructuring. It also uses ... dots but it is used to catch the rest of the parameters coming from the destructure and put it into a Plain Old Javascript Array.

If you destructure an array which has more than two elements with two constants, one a simple constant and another a rest, the rest will take all the other elements of the array other than the first. An example is shown below:

var arr = ['My', 'Name', 'is', 'Bond']

//Apply destructure: 

var [ first, ...others] = arr
first // will print 'My'
second // will print  ['Name', 'is', 'Bond']

Again, Spread and Rest although use same number of dots, have different uses and use cases

Hope it helps!

Owned & Maintained by Saurav Prakash

If you like what you see, you can help me cover server costs or buy me a cup of coffee though donation :)