DEV Community

tq-bit
tq-bit

Posted on • Updated on

Seven advanced techniques for Javascript spread syntax

The three dots ... that represent both of these concepts were introduced with ECMAScript2015. They literally "spread" an array or an object into its elements, which provides you with a great variety of options while coding. For example:

  • Destructuring single or multiple elements.
  • Concat multiple elements into one.
  • Cherry-pick variables you need and sort out those you don't.

I have collected seven common use cases from my latest projects that make use of this flexible approach. Each is as simple as it is powerful.

1) Get rid of unwanted object properties

The idea is simple:

  • Assume you have a Javascript object out of which you need all props but one.
  • You also need the original object at a later point.

You could of course use the delete operator and keep a copy of the original object. Using spread syntax, however, keeps your code more readable.

const domeOfCologne = {
  buildStart: 1248,
  buildHalted: 1560,
  buildFinished: 1880,
  buildingCity: 'Cologne',
  buildingCountry: 'Germany'
}

// Remove the location
const { buildingCountry, ...domeInfo } = domeOfCologne; 

console.log(buildingCountry) // output: 'Germany'
console.log(domeInfo)        // output: {buildStart: 1248, /* ... */}
Enter fullscreen mode Exit fullscreen mode

2) Join elements of several arrays together

A quite common use case is to join elements from distinct arrays. It is as easy as spreading the old arrays and adding them into a new one. Further below, you can also find a more complex method that considers nested arrays as well.

const americanNames = ['Dave', 'Joe', 'John']; 
const germanNames = ['Hans', 'Mertens', 'Astrid'];
const englishNames = ['James', 'Peter', 'Boris']; 

const allNames = [...americanNames, ...germanNames, ...englishNames];
console.log(allNames) // Logs an array including all elements from above
Enter fullscreen mode Exit fullscreen mode

3) Add optional function arguments

Rest parameters in a function's declaration make it easy to define optional arguments. The following function will take in one mandatory argument. It will then apply a function based on its value, using the other arguments passed into the function.

function math(calcMeth, ...numbers) {
  numbers.forEach(num => {
    if (isNaN(num)) {
      throw new TypeError('One or more arguments are not numeric')
    }
  });
  switch (calcMeth) {
    case 'sum':
      return numbers.reduce((prev, curr) => prev + curr, 0);
    case 'multi':
      return numbers.reduce((prev, curr) => prev * curr, 1);
    case 'power': 
        return numbers.reduce((prev, curr) => prev ** curr);
    default: 
      throw new Error(`${calcMeth} is not a valid calculation method`)
  }
}

console.log(math('sum', 2, 3))   // 5
console.log(math('multi', 2, 3)) // 6
console.log(math('power', 2, 3)) // 8
Enter fullscreen mode Exit fullscreen mode

4) Extend an object with additional properties

This technique comes in especially handy when using standard configuration and dynamically extend it. A case in which I've used it myself was with a REST API endpoint that always delivers a standard HTTP - message. I would use the spread operator to additionally add a custom response from the database the frontend dev could then process

 

const standardResponse = {
  status: 400,
  title: 'client-error', 
  message: 'This item is already maintained in the database'
}

const extendedResponse = {
  ...standardResponse, 
  itemId: '123'
}
Enter fullscreen mode Exit fullscreen mode

5) Copy an array or an object

If you want to keep the original state of an item, copying it is a save option. Like this, you have it available for further processing. This might also come in especially handy in reactive contexts, as the copy will be non-reactive.

Note that the new object also has no more reference to the original

const original = {
  name: 'Mona Lisa', 
  creator: 'Leonardo Da Vinci'
}

const copy = { ...original }; 

console.log(copy) // {name: 'Mona Lisa', creator: 'Leonardo Da Vinci'}
console.log(copy === original) // false
Enter fullscreen mode Exit fullscreen mode

6) Remove duplicated objects from an array

This is a more complex one, but it makes perfect use of the spread operator.

  • array.map will pull out the values
  • new Map will make sure that only unique objects are kept
  • ... will iterate over the map and create the array
const pictures = [
  {
    name: 'Mona Lisa',
    painter: 'Leonardo Da Vinci',
  },
  {
    name: 'The Scream',
    painter: 'Edvard Munch',
  },
  {
    name: 'Starry Night',
    painter: 'Vincent van Gogh'
  },
  {
    name: 'The Scream',
    painter: 'Edvard Munch',
  }, {
    name: 'Mona Lisa',
    painter: 'Leonardo Da Vinci',
  },
];

function removeDuplicates(arr) {
  return [...new Map(arr.map((item) => [item.name, item])).values()];
}

console.log(removeDuplicates(pictures)); // Logs the three unique paintings
Enter fullscreen mode Exit fullscreen mode

7) Flatten nested arrays

Nested arrays are nasty. And without libraries such as lodash, you often end up with unnecessarily spaghettified code. What if there was an easier way?

The following function will recursively iterate through an array. It pulls out all elements nested within and joins them in a new array.

const churchesOfMadrid = [
  [
    'Templo de Debod',
    'Iglesia Parroquial de San Jerónimo el Real',
    [
      'San Antonio de los Alemanes',
      'Convento de las Trinitarias Descalzas de San Ildefonso',
      [
        'Basílica de San Francisco el Grande',
        'Basílica Pontificia de San Miguel'
      ],
    ],
  ]
]

function flattenArray(array) {
  const newArray = [];
  const length = array.length
  for (let index = 0; index < length; index++) {
    if (Array.isArray(array[index])) {
      newArray.push(...flattenArray(array[index]))
    } else {
      newArray.push(array[index])
    }
  }
  return newArray
}

const newArray = flattenArray(churchesOfMadrid);
console.log(newArray) // Returns the flattened array item
Enter fullscreen mode Exit fullscreen mode

References

Spread Syntax on MDN

Rest Parameters on MDN

This post was originally published at https://blog.q-bit.me/ten-simple-techniques-for-javascript-spread-and-rest/
Thank you for reading. If you enjoyed this article, let's stay in touch on Twitter 🐤 @qbitme

Top comments (1)

Collapse
 
rodrigodagostino profile image
Rodrigo D’Agostino

Thank you for the article! It definitely opened my mind to new possibilities I wasn’t considering :)