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.
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
Note: The rest operator is symbolized by three dots (
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
Note: The spread operator is symbolized by three dots (
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.
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
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:
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.assignwould trigger them, as opposed to the spread operator.
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.
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:
- The official proposal
- Examples for using the rest opeator
- Examples for using the spread opeator
- “Rest/Spread Properties” by Axel Rauschmayer
Here are the examples which were shown in the article: