By Li357

2017-07-05 19:49:51 8 Comments

I've heard ... referred to both as 'spread syntax' and 'the spread operator', with the latter being a lot more popular. The URL of the relevant MDN documentation suggests that it was initially referred to as the spread operator but later changed to spread syntax, and MDN's list of operators doesn't mention it.

Google seems to suggest the term operator is more popular and accepted, with sites such as the Microsoft documentation and referring to it as such.

Which term would be the most correct in the context of ECMAScript, if any, and why? What about array destructuring assignment?


@Li357 2017-07-05 19:49:51

It's not an operator.

In all senses of the word, it's not one. It has been a huge misconception since it was introduced and despite popular opinion -- it's not one, and there are a few objective points to be made:

  • It doesn't fit the definition of an operator
  • It can't be used as an operator
  • The language specification implies that it's not an operator

It should be mentioned that spread syntax comes in different 'flavors', used in different contexts and are commonly referred to by different names while using the same punctuator. Spread syntax is basically an umbrella term for the application of the ... punctuator, and see Felix Kling's great answer detailing all the uses and names. More explanation about these individuals uses is given in the supplementary answer.

What is an operator?

Semantically, in the context of ECMAScript, operators are just builtin functions that take in arguments and evaluate to a single value -- written in prefix, infix, or postfix notation and usually with symbolic names such as + or /. From Wikipedia:

Simply, an expression involving an operator is evaluated in some way, and the resulting value may be just a value (an r-value), or may be an object allowing assignment (an l-value).

For example, the + operator results in a value such as 2, which is a right-hand-side expression, and the . operator results in an object allowing assignment such as, a left-hand-side expression.

On the surface, the ... punctuator1 looks to be a prefix unary operator:

const baz = [foo,];

But the problem with that argument is that doesn't evaluate to a singular value; it spreads the iterable bar's elements, one by one. The same goes for spread arguments:


Here, foo receives separate arguments from the iterable bar. They're separate values being passed to foo, not just one value. It doesn't fit the definition of an operator, so it isn't one.

Why isn't it an operator?

Another point to be made is that operators are meant to be standalone and return a single value. For example:

const bar = [];

As already mentioned, this works well. The problem arises when you try to do this:

const bar =;

If spread syntax were an operator, the latter would work fine because operators evaluate the expression to a single value but spread doesn't so it fails. Spread syntax and spread arguments only work in the context of arrays and function calls because those structures receive multiple values supplied by spreading array elements or arguments. Evaluating to multiple values is outside of the scope of what an operator is able to do.

What do the standards say?

The complete list of operators is listed in Clauses §12.5 through §12.15 in the ECMAScript 2015 Language Specification, the specification in which ... is introduced, which doesn't mention .... It can also be inferred that it's not an operator. The two main cases mentioned in this answer in which spread syntax is in a production, for function calls (spread arguments) or array literals (spread syntax) are described below:

ArrayLiteral :
  [ Elisionopt ]
  [ ElementList ]
  [ ElementList , Elisionopt ]

ElementList :
  Elisionopt AssignmentExpression
  Elisionopt SpreadElement
  ElementList , Elisionopt AssignmentExpression
  ElementList , Elisionopt SpreadElement

Elision :
  Elision ,

SpreadElement :
  ... AssignmentExpression

And for function calls:

CallExpression :
  MemberExpression Arguments

Arguments :
  ( )
  ( ArgumentList )

ArgumentList :
  ... AssignmentExpression
  ArgumentList , AssignmentExpression
  ArgumentList , ... AssignmentExpression

In these productions, there's a conclusion that can be made: that the spread 'operator' doesn't exist. As mentioned earlier, operators should be standalone, as in const bar = and evaluate to one single value. The syntax of the language prevents this, which means spread syntax was never meant to be standalone. It's an extension to array initializers and function calls, an extension to their grammar.

Why spread 'syntax'?

Syntax, as defined by Wikipedia:

In computer science, the syntax of a computer language is the set of rules that defines the combinations of symbols that are considered to be a correctly structured document or fragment in that language.

Syntax is basically the 'form' of the language, rules that govern what is legal or not regarding how the code should look, and how the code should be written. In this case, ECMAScript's grammar specifically defines the ... punctuator to only appear in function calls and array literals as an extension -- which is a rule that defines a combination of symbols ( that are considered to be legal together, thus it is syntax similar to how an arrow function (=>) is not an operator, but syntax2.

Calling ... an operator is a misnomer. An operator is a builtin function that takes in arguments (operands) and is in the form of prefix, infix, or postfix notation and evaluates to exactly one value. ..., while satisfying the first two conditions, does not satisfy the last. ..., instead, is syntax because it is defined specifically and explicitly in the language's grammar. Thus, 'the spread operator' is objectively more correctly referred to as 'spread syntax'.

1 The term 'punctuator' refers to punctuators in ECMAScript 2015 and later specifications. These symbols include syntax components and operators, and are punctators of the language. ... is a punctuator itself, but the term 'spread syntax' refers to the whole application of the punctuator.

2 => itself is a punctuator, just as ... but what I'm referring to specifically is arrow function syntax, the application of the => punctuator ((…) => { … }), just as spread syntax refers to the application of the ... punctuator.

@Patrick Roberts 2017-07-05 19:56:02

Upvoted for the research. Still wondering why this matters though? If it's colloquially known as the "spread operator" already, I doubt anyone will misunderstand what is meant in a conversation.

@Li357 2017-07-05 19:58:18

@PatrickRoberts You're correct, but I wanted to make a distinguishment. The biggest problem for me was there was not a single authoritative post that gave a sure answer to the question, and the question stemmed from why MDN had syntax while everyone else had operator. I just wanted to share my knowledge but also show the difference.

@estus 2017-07-05 20:09:28

@PatrickRoberts Let's say the one is about to make a career as JS grammar nazi but still doesn't know if he/she should punish people who say 'spread operator'. This answer provides a very good explanation.

@RobG 2017-07-06 01:09:58

For me, ... is a punctuator that is used in spread syntax and rest parameters, it's neither operator nor syntax by itself. It's equivalent to other punctuators like ,, ; and : which are used in named parts of the grammar (parameter lists, statements, object literals) but aren't called "operators". Also, the latest version of the spec is ECMAScript 2017, I guess you quoted 2015 as that's where ... was introduced. Lastly, §12.5 to 12.6 mention all the operators and ... isn't one of them. Sorry, can only give you one up–vote for your efforts. ;-)

@Li357 2017-07-06 01:11:35

@RobG Yeah, I quoted the 6th edition because it was introduced then. I'll make sure to edit in and mention that all the operators are mentioned, or you could if you want.

@Li357 2017-07-06 01:20:45

@RobG I agree with your statement about ... being a punctuator -- the literal three dots itself is a punctuator, but the actual way it is applied to array initializers and rest parameters I would call syntax. Just my thoughts.

@RobG 2017-07-06 02:53:35

Agree, just commenting. I'd rather the author edit the article, otherwise it gets pretty messy. ;-)

@Ben 2017-07-06 07:43:11

Thank you for doing this research.

@Bergi 2017-07-08 16:28:00

The punctuator does not satisfy the operator criteria even in array destructuring. Even though it is used like (not "as") a unary operator, it does not "evaluate to a single value". In fact, the expression does not evaluate to anything at all - it's used in the assignment operation, but not more. And while the bar variable ends up with a single value, that's not a necessity - the "operand" can be any assignable target expression with as many identifiers as imaginable, e.g. in let [first, ...[second, third]] = … or let [...{0: first, length: x}] = ….

@Bergi 2017-07-08 16:47:52

Yes, that might help. Or we just move it to a second answer (to keep it on the platform) that repeats everything from "On the surface, …" but talks about rest instead of spread syntax.

@Felix Kling 2017-07-10 21:22:00

FWIW, not sure if this should be in this answer or the other, but it might be worth encouraging people to call the thing as what is depending on the context: rest element, rest parameter, spread argument or spread element (that's what I tried to explain in my answer about this topic).

@Li357 2017-07-10 21:38:48

@FelixKling Actually, instead of reinventing the wheel in terms of answers, I'd rather just link to your great answer instead of rewriting the same content.

@Felix Kling 2017-07-10 21:39:35

That's fine for me as well ;)

@Michael Gummelt 2019-05-06 21:29:14

"Semantically, in the context of ECMAScript, operators are just builtin functions that take in arguments and evaluate to a single value" Not really. The ternary operator, for example. doesn't "take in arguments" like a function invocation does, since it short circuits.

@Li357 2019-05-08 00:31:00

@MichaelGummelt The point isn't that operators are some concrete function call with argument lists, but that operators represent some abstract operation listed in the spec that evaluate to a single value - emphasis on single value.

@Michael Gummelt 2019-05-10 18:58:10

@Li357 That may be the author's intended point, but it isn't what he wrote.

@Li357 2019-05-10 19:32:12

@MichaelGummelt I am the author. You're free to edit as you like if you'd like to clarify so.

@Li357 2017-07-08 17:47:07

Other uses of the syntax

There are other numerous uses of spread/rest syntax not covered in the main answer. They include:

  • Rest syntax in function parameters
  • Array and object1 destructuring assignment
  • Object spread syntax in object literals1

Rest syntax

A use for spread syntax, commonly referred to as rest syntax, is used for a variable number of arguments in a function's arguments. This differs from spread arguments, used to pass arguments to a function call based on an iterable's elements. For example:

function add(...addends) {

Here, rest syntax is used for the function add to receive the rest of the arguments in the identifier addends. This does seem to evaluate to a singular value as addends is an array of the passed arguments, but what if we tried:

function foo(...[bar, baz]) {

Here, bar and baz would both be assigned a value corresponding to the first and second arguments passed -- thus this doesn't always evaluate to one value. The underlying problem is that ...addends in the first example and ...[bar, baz] in the second doesn't actually evaluate to a value at all - it's just used during the operation of assigning an array of the arguments to the identifier. Thus, it's syntax to allow a variable number of arguments to a function, not an operator.

Destructuring Assignment

Spread syntax can also be used during array destructuring assignment and is actually referred to as a rest element in the language specification (because when using in destructuring, it gets the rest of the destructured iterable). A convincing argument can be made as this does seem like an operator:

const [] = [1, 2, 3];

It's used like a prefix unary operator. Here, bar evaluates to [1, 2, 3] — which is a single value. But this doesn't always happen, for example:

const [first, ...[second, third]] = [1, 2, 3];

Here, first, second, and third evaluate to 1, 2, and 3 respectively. But ...[second, third] assigns to two identifiers, not one, and doesn't evaluate to a singular value, but two. Just like rest syntax, the underlying problem is that in the first example and ...[second, third] in the second doesn't actually evaluate to a value at all -- it's just used during the operation of assignment. Thus, it isn't an operator at all2, just new sytax to aid in unpacking values.

Object spread syntax

A final use for spread syntax is in object literals, commonly referred to as 'object spread properties' in which a target object's own enumerable properties are spread to another, for example:

const foo = { };

This isn't an operator, just like array spread syntax isn't an operator. The concept is the same, instead of indices and elements in arrays, bar's enumerable keys and values are spread to foo. Here, a collection of bar's properties is spread -- not just one single value, thus it does not fit the definition of an operator.

1 Object rest/spread properties are currently in the Stage 3 proposal for ECMAScript, and will very likely be added in the near future

2 Another problem with destructuring assignment being an operator, aside from semantics, is that the language specification defines it as supplemental syntax --  not a supplemental operator, and rightfully so. It’s not standalone, as this won’t work:

const = [1, 2, 3, 4];

It’s contextual, only allowed in, by the language’s grammar, object literals and array literals that are left-hand-side expressions. It’s also grammar that refines the interpretation of a left-hand-side expression. Again, this is an extension to add new syntax to the language, a refinement to existing grammar. That reaffirms the argument with specification.

Related Questions

Sponsored Content

3 Answered Questions

[SOLVED] Equality operator overloads: Is (x!=y) == (!(x==y))?

45 Answered Questions

[SOLVED] What is the preferred syntax for defining enums in JavaScript?

35 Answered Questions

[SOLVED] What is the !! (not not) operator in JavaScript?

  • 2009-04-24 08:13:58
  • Hexagon Theory
  • 463644 View
  • 2703 Score
  • 35 Answer
  • Tags:   javascript operators

8 Answered Questions

[SOLVED] Is there a "null coalescing" operator in JavaScript?

1 Answered Questions

11 Answered Questions

[SOLVED] Why is f(i = -1, i = -1) undefined behavior?

1 Answered Questions

[SOLVED] Benefits of ES6 Reflect API

3 Answered Questions

[SOLVED] syntax for es6 destructuring from an array into an object

4 Answered Questions

[SOLVED] What is the "double tilde" (~~) operator in JavaScript?

  • 2011-05-11 23:18:14
  • jismo
  • 109531 View
  • 485 Score
  • 4 Answer
  • Tags:   javascript

Sponsored Content