In JavaScript, the same syntax – triple dots (
...
) – is used for two different mechanisms:- Rest syntax is for receiving data.
- Spreading is for sending data.
This blog post examines how these mechanisms work and why they are not operators.
Table of contents:
Receiving data: rest syntax
A rest parameter is a special kind of parameter that receives all remaining arguments of a function call via an Array:
> function myFunc(first, ...remaining) { return {first,remaining} } > myFunc('a', 'b', 'c') { first: 'a', remaining: [ 'b', 'c' ] }
We can also use rest syntax in Array-destructuring:
> const [head, ...tail] = ['a', 'b', 'c']; > head 'a' > tail [ 'b', 'c' ]
And we can use it in object-destructuring:
> const {first: f, ...remaining} = {first: 'Jane', last: 'Doe', age: 43}; > f 'Jane' > remaining { last: 'Doe', age: 43 }
Sending data: spreading
Spreading into a function call turns Array elements into function call arguments.
> function returnArgArray(...args) { return args } > returnArgArray(...['x', 'y', 'z']) [ 'x', 'y', 'z' ]
We can also spread Arrays into Array literals:
> [...['a', 'b'], 'c'] [ 'a', 'b', 'c' ]
And we can spread objects into object literals:
> {...{a:1, b:2}, c:3} { a: 1, b: 2, c: 3 }
Rest and spread are not operators
Operators such as
+
or await
are used to write independent expressions that evaluate to values. Those expressions can be used in many contexts.In contrast, rest and spread are part of their surroundings. That’s why they shouldn’t be called operators:
- Rest syntax: rest parameters (function definitions), rest elements (Array-destructuring), rest properties (object-destructuring)
- With spreading, I usually say: “spreading into ...” (function calls, Array literals, object literals).
Further reading (use cases etc.)
Rest syntax:
Spreading: