JavaScript: dot dot dot by example
Tags: javascript, rest, spread
Published: 2019-08-29 13:21:47

---
title: JavaScript: dot dot dot by example
published: true
description: 
tags: JavaScript, Rest, Spread
---

Do you know all use cases for the three dots in JavaScript? 


Little History: 

First, they added this syntax for arrays and parameters in ES6 (spread and rest elements). 
In 2018, they added it for objects (spread and rest properties).

And all features share the same syntax 

`...`

That can be pretty confusing if you see that syntax for the first time.
This post is a collection of examples how you can use them in your code. 


## Let's start with: Spread Elements
Want to copy all elements from an array to another array?
Use `...` (spread elements) to shallow(!) copy an array.
```javascript
const fruits = ["apple", "banana", "coconut"];
const fruitsCopied = [...fruits];
// fruitsCopied: ["apple", "banana", "coconut"]
```

You can adds another element on the fly.
```javascript
const fruits = ["apple", "banana", "coconut"];
const moreFruits = [...fruits, "pear"];
// moreFruits: ["apple", "banana", "coconut", "pear"]
```

Let's imagine that we have this stupid `print` function.
With `...` we can simply spread elements of an array as arguments to a function.

```javascript
const print = (first, second, third) => console.log(`first: "${first}" second: "${second}" third: "${third}"`);

const fruits = ["apple", "banana", "coconut"];
print(...fruits);
// first: "apple" second: "banana" third: "coconut"
```

We can also spread an array of numbers into the Math.max method. Isn't that neat?
```javascript
const numbers = [1, 5, 23, -5, 2, 42];
Math.max(...numbers);
```
## Next: Rest Elements
Want to split an array into head and tail?
Here we are destructuing an array and use  `...` (rest element) to collect all elements which are not already picked by the destructuring pattern into `tail`. 
```javascript
const [head, ...tail] = [1, 2, 3];
// head: 1
// tail: [2, 3]
```

Before, we already used `...` to spread elements as arguments to a function on the call-site. Now we use `...` (rest parameter) to collect all passed parameter into `args`.
```javascript
function getNumberOfPassedArguments(...args) {
	return args.length;
}

getNumberOfPassedArguments("apple", "banana", "coconut");
// 3
```

Do you know `compose` from Ramda or Underscore? Look how short the implementation is:
```javascript
const compose = (...fns) => x => fns.reduceRight((acc, cur) => cur(acc), x);

const fivePercentDiscount = price => price * 0.95;
const germanTax = price => price * 1.19;

const getProductPrice = compose(germanTax, fivePercentDiscount);
getProductPrice(10);
```

## Let's get to objects. Here we can do pretty much the same: Spread Properties

With `...` (spread properties) we can shallow copy all (own enumerable)  properties (key and value) of an object.
```javascript
const person = {name: "Thomas", age: 28};
const copiedPerson = {...person};
```

We can spread the properties and immediately overwrite properties during creation.
```javascript
const thomas = {name: "Thomas", age: 28};
const peter = {...thomas, name: "Peter"};
```

We can overwrite an arbitrary number of properties if we already defined some properties and then spread properties of another object.
```javascript
function initConfig(overwrites) {
	const defaults = {useSSL: true /*,  ... */};
	return {...defaults, ...overwrites};
}	
```

Want to have optinal properties on an object, but don't want to mutate the object after creation?
Here are to ways:
```javascript
const shouldAddB = true;
let obj1 = {a:1, ...(shouldAddB && {b:2})};
// or
let obj2 = {a:1, ...(shouldAddB ? {b:2} : {})};
```
## Rest Properties
We can also use `...` (rest properties) to copy a subset of properties into an object. In the destructuring pattern we list the properties, which we don't want to have in the new object, and collect the remaining properties with the `...` rest properties into `personWithoutAge`.
```javascript


const {age, ...personWithoutAge} = {name: "Thomas", age: 28, country: "Germany"};
// personWithoutAge: {name: "Thomas", country: "Germany"}
```

Which one do you use in your code and do you have more use cases? Please let us know!