What Do Three Dots Mean in JavaScript
You probably have come across the ellipsis while reading. In writing, ellipsis can be used to omit words from a sentence that would obviously be there based on what was said before. Similarly, it can be used in JavaScript to expand all array elements or object keys in places where they are expected to be specified one by one.
Spread Syntax
The ellipsis or ...
in JavaScript is called the spread syntax. It has multiple handy uses that, as mentioned before, allow us to omit some code to achieve the desired result with less typing.
Spread syntax can be used on literals such as arrays, objects, strings, and it can also be used in function calls.
Arrays
When used on arrays, the spread syntax can copy one array’s contents to another.
const fruits = ['apple', 'orange', 'watermelon', 'mango'];
/* ['carrot', 'garlic', 'broccoli', 'potato',
'apple', 'orange', 'watermelon', 'mango'] */
const veggiesAndFruits = ['carrot', 'garlic', 'broccoli', 'potato', ...fruits];
And depending on where it is used, you can control the copied contents location.
/* ['carrot', 'garlic', 'apple', 'orange',
'watermelon', 'mango', 'broccoli', 'potato'] */
const veggiesAndFruits = ['carrot', 'garlic', ...fruits, 'broccoli', 'potato'];
Spread syntax can also be used to concatenate two arrays together, which is basically copying the first and the second array into a new array.
const fruits = ['apple', 'orange', 'watermelon', 'mango'];
const vegetables = ['carrot', 'garlic', 'broccoli', 'potato'];
const freshGoodies = [...fruits, ...vegetables];
It can also be used to add a new element to an existing array.
let fruits = ['apple', 'orange', 'watermelon', 'mango'];
// [ 'apple', 'orange', 'watermelon', 'mango', 'banana' ]
fruits = [...fruits, 'banana']
Can’t I just reassign an array to copy it to a new variable?
No. In JavaScript, assigning an array to a variable happens by reference. It can be dangerous to do so since it can introduce unexpected bugs.
const fruits = ['apple', 'orange', 'watermelon', 'mango'];
const sameOldFruits = fruits;
fruits.push('pineapple');
sameOldFruits [0] = 'banana';
// ['banana', 'orange', 'watermelon', 'mango', 'pineapple']
console.log(fruits);
// ['banana', 'orange', 'watermelon', 'mango', 'pineapple']
console.log(sameOldFruits);
Modifying either sameOldFruits
or fruits
makes a change to the other array as well. This can be avoided using the spread syntax. This way we are creating a new array and copying the old array’s elements by their value to the new array.
const fruits = ['apple', 'orange', 'watermelon', 'mango'];
const sameOldFruits = [...fruits];
fruits.push('pineapple');
sameOldFruits [0] = 'banana';
// ['apple', 'orange', 'watermelon', 'mango', 'pineapple']
console.log(fruits);
// ['banana', 'orange', 'watermelon', 'mango']
console.log(sameOldFruits);
Be careful with 2d arrays.
Although the spread syntax can be used to safely copy an array to a new variable, the same cannot be done with multidimensional arrays. The spread syntax goes only one dimension or level deep into the array to copy the elements by value.
const fruitsAndVegetables = [['apple', 'orange'], ['carrot', 'potato']];
const copyOfFruitsAndVegetables = [...fruitsAndVegetables];
copyOfFruitsAndVegetables[0] = ['banana', 'mango'];
copyOfFruitsAndVegetables[1][0] = 'garlic';
copyOfFruitsAndVegetables[1][1] = 'broccoli';
// [['apple', 'orange' ], [ 'garlic', 'broccoli']]
console.log(fruitsAndVegetables);
// [['banana', 'mango' ], ['garlic', 'broccoli' ]]
console.log(copyOfFruitsAndVegetables);
We can see that if change the value in the first dimension of copyOfFruitsAndVegetables
, which we access with [0]
, only this array is affected. But, if we tamper with the values in the second dimension, which is accessed with [1][0]
and [1][1]
, these values change in both arrays.
Objects
Similarly to arrays, an object can be copied to a new variable with the spread syntax.
const book = {
title: 'Interestig Book',
pages: 534,
color: 'green',
};
// { title: 'Interesting Book', pages: 534, color: 'green' }
const greenBook = {...book};
And, we can also combine two objects into one.
const book = {
title: 'Interesting Book',
pages: 534,
};
const bookCover = {
color: 'green',
};
// { title: 'Interesting Book', pages: 534, color: 'green' }
const greenBook = {...book, ...bookCover};
Whenever the spread syntax is used on multiple objects that have a common key, the last object that is being expanded, will determine the value that the property will hold in the final object.
const book = {
title: 'Interesting Book',
pages: 534,
color: 'blue',
};
const heavyBook = {
pages: 1252,
color: 'red',
}
const bookCover = {
color: 'green',
};
// { title: 'Interesting Book', pages: 1252, color: 'green' }
const heavyGreenBook = {...book, ...heavyBook, ...bookCover};
Strings
Strings can be split into characters by using the spread syntax.
const text = 'Hello world';
//[ 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
const characters = [...text];
Functions
We can provide the multiple arguments, that a function expects, using the spread syntax.
function concatenateCharacters(a, b, c) {
return a + b + c;
}
const characters = ['h', 'e', 'y'];
// hey
concatenateCharacters(...characters);
In this example, the array’s elements get placed in each of the invoked concatenateCharacters
function’s arguments respectively.