loading...
Cover image for Three dots ( … ) in JavaScript

Three dots ( … ) in JavaScript

sagar profile image Sagar Updated on ・2 min read

Hey! I'm Sagar. I love to write tutorials and articles to help developers better understand the magic of JavaScript. If you have any questions about the article, leave a comment and I'll get back to you, or find me on twitter @sagar_codes.

In this article, we are going to discuss a feature introduced in ES6 that is spread operator and rest operator. 🔥 🔥 🔥

I've become a big fan of the three dots that may change your style of solving the problem within JavaScript. We can use three dots … in two different ways as spread operator and rest operator.

Rest Parameters 😴

With rest parameters, we can gather any number of arguments into an array and do what we want with them. Rest parameters have been introduced to reduce the boilerplate code that was induced by the arguments. 🙌

function myFunc(a, b, ...args) {
 console.log(a); // 22
 console.log(b); // 98
 console.log(args); // [43, 3, 26]
};
myFunc(22, 98, 43, 3, 26);

In myFunc's last parameter prefixed with … which will cause to all remaining arguments placed within the javascript array.

The rest parameters gather all remaining arguments so there is no sense 😕 to add rest parameters before the last parameter. Rest parameter must be the last formal parameter.

function myFunc(arg1, ...rest, arg2) {
  // arg2 ?
}

Rest parameters can be destructured (arrays only), that means that their data can be unpacked into distinct variables.

function myFunc(...[x, y, z]) {
  return x * y* z;
}

myFunc(1)          // NaN
myFunc(1, 2, 3)    // 6
myFunc(1, 2, 3, 4) // 6 (fourth parameter is not destructured)

Spread Operators ✨

The spread operator is used to expand elements of an iterable (like an array) into places where multiple elements can fit.

function myFunc(x, y, ...params) { // used rest operator here
  console.log(x);
  console.log(y);
  console.log(params);
}

var inputs = ["a", "b", "c", "d", "e", "f"];
myFunc(...inputs); // used spread operator here
// "a"
// "b"
// ["c", "d", "e", "f"]

There have always been a variety of ways to combine arrays, but the spread operator gives use a new method for combining arrays:

const featured = ['Deep Dish', 'Pepperoni', 'Hawaiian'];
const specialty = ['Meatzza', 'Spicy Mama', 'Margherita'];

const pizzas = [...featured, 'veg pizza', ...specialty];

console.log(pizzas); // 'Deep Dish', 'Pepperoni', 'Hawaiian', 'veg pizza', 'Meatzza', 'Spicy Mama', 'Margherita'

With spread operator, Shallow-cloning (excluding prototype) or merging of objects is now possible using a shorter syntax than Object.assign().

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

👉 Conclusion

When we see three dots (…) in the code, it's either rest parameters or the spread operator.

There's an easy way to distinguish between them:

  1. When three dots (…) is at the end of function parameters, it's "rest parameters" and gathers the rest of the list of arguments into an array.

  2. When three dots (…) occurs in a function call or alike, it's called a "spread operator" and expands an array into a list.

Thanks for reading. I hope you like this article feel free to like, comment or share this article with your friends.

😄 Happy Coding…

Posted on by:

sagar profile

Sagar

@sagar

Passionate software engineer with 4+ years of experience in building products for numerous domains like fin-tech, real estate, video streaming, retail, and now e-commerce.

Discussion

markdown guide
 

The other usage of ... I found is very useful:

Converting an iterable object:

// An array of HTMLElement, not the annoying NodeList object
const array = [...document.querySelectorAll('div')]; 

Even a generator, how cool is that?

const array = [...(function*() {
  for (let i = 10; i > 0; i--) {
    yield i;
  }
  yield 'Launch';
})()];

console.log(array);    // [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, "Launch"]
 

Great article! This was a really great explanation of spread/rest.

I'd also add that three dots on the left-side of an equals sign is "destructuring assignment" and allows you to "pull out" values.

ex:

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest); // [30,40,50]

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
console.log(a); // 10 
console.log(b); // 20 
console.log(rest); // { c: 30, d: 40 }
 

I missed writing about destructor. Thanks

 

Great explanation! I knew about the rest parameters and even used them in my code, and now, thanks to your explanation, I will also use the spread operator. First of all, I replace all Object.assign() in my code with a short form.

 

Thanks for your feedback.

 

Hi I noticed that the Shallow-cloning isn't working in Edge (18)

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };

Result: error in console 'Expected identifier, string or number'
 

Wonderful explanations, I've found this to be one of the more confusing elements of new JS.

 

Me too, it seems to promote a „many positional arguments“ programming style instead of composing things into useful objects 🤔 Also the destructuring on the method definition is a part of this thing... i think

 

Yes, Ben I found three dot operator confuse when use try to us in project. Thanks for your feedback.

 

In a document of Gatsby, there is a line of code that ... followed by nothing. What does it mean here?

import React from "react"
import { graphql } from "gatsby"
export default function IndexPost( props ) {
  return (...)
}
export const query = graphql`
  fragment SiteInformation on Site {
    siteMetadata {
      title
      siteDescription
    }
  }
`
 

maybe Gatsby trying to say there should JSX written by the user and this is not valid case.

 

Excellent article.

Small edit to replace "use" with "us":
"There have always been a variety of ways to combine arrays, but the spread operator gives use a new method for combining arrays:"
Should be:
"There have always been a variety of ways to combine arrays, but the spread operator gives us a new method for combining arrays:"

 

Thanks mate! It was clear and helpful.

 
 

Great run down of two great new features!

 

wow thank you! awesome explanation :)

 
 
 

Tysm for this article! I have been trying to figure this out all night and then I found this article!!

 

Most welcome 👍🏻

 
 

It's important to note that this feature is available in all major browsers except for IE11

caniuse.com/#feat=rest-parameters

 

There's also function application:

function cube(x, y, z) {
  return x * y * z;
}

cube(...[2, 5, 10]);
//> 100

Using ... you can send an array as separate arguments.

 

Thanks for the great explanation Sagar, rest/spread basically performs the exact same job as the "splat operator" in php.