DEV Community

loading...
Cover image for Spread Syntax "Three-dots" Tricks You Can Use Now

Spread Syntax "Three-dots" Tricks You Can Use Now

girlie_mac profile image Tomomi Imura 🐱 Updated on ・4 min read

This articles is created based on my own tweet posted on May 22, 2020


ES6 (ECMAScript 2015, the 6th edition) was finalized 5 years ago, and brought us a significant amount of new syntax and features to help you write complex code better and simpler.

I am assuming that many of you have consumed more calories from the syntactic sugar by adopting new features like class declarations, let / const, and arrow function expression, and so on, but how about some of the lesser-known Spread operator?

Here, I would like to share some good usages of spread operator, a.k.a three-dots that I've found while I was coding (and StackOverflowing, I don't lie about how I code!).

What do Three Dots do?

First, there are two "three-dots" sugars introduced in ES6. One is Rest parameter, which allows us to use an arbitrary number of arguments, and another is Spread operator, which also has the similar syntax with three dots, but it is more like the reversed version- it takes the array itself, not arguments.

In this article, I am showing tricks that uses spread syntax. Looking at the practical examples may be far easier to understand what it does than by reading the definitions!


Concat

You say "cat" so I say meow.

Let's concatenate two arrays. Here we have two arrays that represent cat fur coat colors:

const arr1 = ['solid', 'bicolor', 'tabby'];
const arr2 = ['calico', 'tortoiseshell'];
Enter fullscreen mode Exit fullscreen mode

This is how we traditionally did before ES6 using concat():

var conCats = arr1.concat(arr2);
// ['solid', 'bicolor', 'tabby', 'calico', 'tortoiseshell']
Enter fullscreen mode Exit fullscreen mode

Now you can simply write with the ES6 spread syntax like this:

const conCats = [...arr1, ...arr2]; 
// ['solid', 'bicolor', 'tabby', 'calico', 'tortoiseshell']
Enter fullscreen mode Exit fullscreen mode

Convert a string to array

Have you been asked to reverse a string, or check if a string is a palindrome at job interviews? The questions you got may be more complex, but these are pretty common interview questions for software engineers.

Anyway, the first step to solve the question is likely to convert the given string to an array.

You have a given string:

const str = 'kitty';
Enter fullscreen mode Exit fullscreen mode

With pre-ES6 JavaScript, use split() to get each letter in an array:

var newArr = str.split(''); // ['k', 'i', 't', 't', 'y'];
Enter fullscreen mode Exit fullscreen mode

Now with the ES6 spread syntax, you can achieve the same as:

const newArr = [...str]; // ['k', 'i', 't', 't', 'y'];
Enter fullscreen mode Exit fullscreen mode

Find Max or Min

Let's say, you have a given set of numbers,

10, 9, 6, 12 
Enter fullscreen mode Exit fullscreen mode

To find the largest (or smallest) number from the set of numbers, you can use Math.max() (or Math.min()) and pass the given numbers as input parameters like this:

var max = Math.max(10, 9, 6, 12);
Enter fullscreen mode Exit fullscreen mode

Now with the ES6 spread syntax, you can pass an array of numbers:

const nums = [10, 9, 6, 12];
const max = Math.max(...nums); // 12
Enter fullscreen mode Exit fullscreen mode

Copy an Array

You can also create a shallow copy of an array with the spread syntax.

You have an array,

const allCatNames = ['chewie', 'leia', 'yoda', 'chewie', 'luke', 'leia'];
Enter fullscreen mode Exit fullscreen mode

And onne way to get a shallow copy of the array with the pre-ES6 is using slice():

var allCatNamesCopy = allCatNames.slice();
Enter fullscreen mode Exit fullscreen mode

Now with ES6 spread syntax, you can simply do:

const allCatNamesCopy = [...allCatNames];
Enter fullscreen mode Exit fullscreen mode

Remove Dups from an Array

The array, allCatNames above has some duplicated values (chewie and leia appeared twice in the list). If want to remove the duplicates, you'll write multiple lines of code with pre-ES6 JavaScript-

You probably would iterate the array. And at each loop, map each value in an object to track if the key in the object is unique, and if yes, the value is pushed to a new array. Then at the end of the loop, you have the new array only with unique values.

You can actually achieve this in one line of code with spread syntax by creating a new array with combination of the spread syntax with the Set object:

const catNames = [...new Set(allCatNames)]; 
// ['chewie', 'leia', 'yoda', 'luke'];
Enter fullscreen mode Exit fullscreen mode

Ta-da, this saves a lot of code!

Collecting HTML Elements in an Array

If you are a front-end JavaScript developer, this trick may be useful when you manipulate DOM-

Let's say, when you re trying to grab every element with the class name, .cat, you probably use querySelectorAll() to get the collection of the DOM nodes.

But document.querySelectorAll('.cat') returns a static NodeList, which is an array-like, but not exactly an array that you can iterate over it.

So in some occasions, you need to convert a NodeList to Array. Traditionally, you probably have been writing code like this, which doesn't seem so intuitive:

var catElementArray = [].slice.call(document.querySelectorAll('.cat'));
Enter fullscreen mode Exit fullscreen mode

Now with the spread syntax, you can rewrite as followings:

const catElementArray = [...document.querySelectorAll('.cat')];
Enter fullscreen mode Exit fullscreen mode

This looks more intuitive, doesn't it?


Well, if you like the three-dots notation or not, now you see that the spread operator can be quite handy when you work with arrays and objects.

I would be happy if I just convinced you to use the three-dots in your daily code from now on. Surely, there are more clever ways to write code with using the spread operator, so if you know the tricks, please share with me and the rest of the JS community!

Wants to find out more about ES.Next?

I will be giving a talk, ECMeowScript - What’s new in JavaScript Explained with Cats at Forward JS (San Francisco virtual) and Web Directions (Sydney virtual) in September, so I hope you can catch my talk! 🐱

(Edit: Conference month has been updated.)

Ciao!

Discussion (14)

pic
Editor guide
Collapse
mrwensveen profile image
Matthijs Wensveen • Edited

Instead of slice, Array.from can be useful too:
Array.from(document.querySelectorAll(".cat"))

Collapse
girlie_mac profile image
Tomomi Imura 🐱 Author

This looks clean and intuitive too <3 Thank you for sharing!

Collapse
hsimah profile image
hsimah • Edited

Also similar to spread is the rest operator - you can team it up destructuring to get properties out of objects:

const obj = {
  prop1: 1,
  prop2: 2,
  prop3: 3
};
const {prop1, ...restObj} = obj;

This is great for React props which need to be passed to child components.

And then to shallow copy an object:

const newObj = {
  ...obj,
  prop1: 2
};

Also great in React for setting state or in a Redux reducer.

Collapse
girlie_mac profile image
Tomomi Imura 🐱 Author

Yes, I've found it super useful too! Especially when I am trying to grab data from some API that returns a request with a JSON. Destructuring comes really handy to assign the data to variables and I love that!

Collapse
szymondziewonski profile image
Szymon Dziewoński • Edited

The reason you might use Array.prototype.slice.call() or [].slice.call() is because of lack support for IE for Array.from() and [...](spread operator) so even its good to know, its kind of useless as "trick" . Anyway thank you for rest examples, good to refresh memory :)

Collapse
girlie_mac profile image
Tomomi Imura 🐱 Author

Ahhh IE. Web devs nowadays must be happier people that used to be.

Collapse
girlie_mac profile image
Tomomi Imura 🐱 Author

Another example I thought about (well, this is the variant of the "string to array") -

const isAnagram = (str1, str2) => {
  return [...str1].sort().join() === [...str2].sort().join();
};

isAnagram("deno", "node"); // true
Collapse
robincsamuel profile image
Robin C Samuel

One other reason I use spread is to conditionally add a key to an object,

const user = {
     firstName: input.firstName,
     ...(input.lastName ? { lastName: input.lastName } : null)
}
Collapse
miggu profile image
miggu • Edited

I use this ALL THE TIME, you can use an empty object {} as well instead of null

Collapse
bashunaimiroy profile image
Bashu Naimi-Roy

I might end up using this, thanks Robin!

Collapse
prashanthpprabhu profile image
Prashanth Prabhu

When you are concating 2 arrays also it is a shallow copy. Right?

Collapse
girlie_mac profile image
Tomomi Imura 🐱 Author

Yes, a good point! It doesn't recurse into nested arrays so it returns a new array with shallow copies.

Collapse
cbloss profile image
cbloss

This is all great!! Thanks for this collection!!

Collapse
damsalem profile image
Dani Amsalem

That last one, Collecting HTML Elements in an Array is excellent and immediately useful for me!