ECMAScript - Object Rest/Spread Properties in ES2018 (ES9)

March 10, 2018 4 min read ECMAScript

This article will examine the "Object Rest/Spread Properties" proposal which has been reached stage 4 in the TC39 process and will be included as part of ES2018 (ES9) specification.

Preface

To better understand what the proposal brings - we should get acquainted with rest and spread operators in the context of array destructuring and array literals.

Array Destructuring

As part of ES2015 (ES6), we introduced a new operator in array destructuring - the rest operator.

When destructuring an array - the rest operator combines the remaining elements of an array into a variable:

We use destructuring assignment to pick the first element into x and all the others into remaining.

Note: The rest operator is symbolized by three dots (...).

Array Literals

As part of ES2015 (ES6), we introduced a new operator in array literals - the spread operator.

When initializing an array - the spread operator copies the elements of an existing array into the new array:

We initialize a new array with the number 1 and all the elements of existingArray.

Note: The spread operator is symbolized by three dots (...).

The Proposal

Object Rest/Spread Properties is an approved proposal for ES2018 (ES9) specification that was created by Sebastian Markbåge. This proposal provides the ability to use rest and spread operators on top of objects.

Object Destructuring

Analogously to the array - when destructuring an object, the rest operator combines the remaining enumerable own properties of that object into a new object, without those which weren’t already picked off by the destructuring pattern:

We use destructuring assignment to pick the value of “x” property into x and all the others enumerable own properties into an object which’s named remaining.

On top of that, we can perform a shallow clone for an object:

All the enumerable own properties are copied to the new object, except for prototypes.

Sometimes we’ve nested objects. In that case, we could use the rest operator multiple times to pick off the values we actually want:

This example is a bit tricky - because we use array destructuring assignment to pick the first element of “x” into x1 and then - inserting all other elements into remaining. However, it’s easy to see that array destructuring is nested inside an object destructuring, so that, the second rest operator takes all the properties (which were already picked off) and inserts those into allRemaining (which means the y property in practice).

In addition to what’s being said, these cases are invalid - so be sure to avoid them:

Object Literals

Analogously to the array - when initializing an object, the spread operator copies the enumerable own properties of an existing object into the new object:

A new object is initialized with all the properties of existingObject and followed by foo function. Notice that the order is important, because it affects the insertion. In case we’d use the operator after foo, we’d get that function as the first enumerable own property.

Moreover, performing a shallow clone is fairly simple:

Notice that clone doesn’t include the prototypes as before.

Well, it seems like an easy way to clone (compared to Object.assign), however, there are some differences:

  • In case the cloned object has setters, Object.assign would trigger them, as opposed to the spread operator.
  • Using Object.assign, we can prevent from creating own properties via inherited read-only properties, while the spread operator is unable to do it.

Let’s take advantage of this operator to merge between objects:

For the record, it’s equivalent to the following line:

Here’s how to override properties from an existing object:

Let’s see how we define default values for properties:

In case our sampleObject has a z property - it’ll be overridden as we’ve seen before.

Summary

We explored today the rest and spread operators in terms of objects, and we learned how to use these in object destructuring and object literals.

Here are some useful references:

Here are the examples which were shown in the article: